CLI Local Debugging
Generate a CLI Debug Token and execute EdgeCron Endpoint requests from your own machine.
CLI local debugging temporarily routes EdgeCron Delivery Attempts through the CLI on your machine. The CLI requests each configured Endpoint URL locally, so you can test public endpoints, localhost services, Task Runs, event fanout, and retry behavior without a tunnel.
Generate Token
01
Open CLI Session
02
Trigger Task Run
03
Forward Locally
04
Write Result
05
When to use it
This flow is for development and integration testing. When the CLI is online and the forwarding scope matches, EdgeCron sends the delivery to your CLI first, and the CLI requests the configured Endpoint URL from your machine.
Live deliveries use the original Endpoint URL
Starting with CLI v0.1.2, Core sends the complete Endpoint URL through CLI Gateway. The CLI requests that URL from your machine, so public URLs such as https://www.baidu.com and local URLs such as http://127.0.0.1:7749/ping both keep their original scheme, host, port, path, and query. The listen --host/--port address is only a fallback for replay and older gateway payloads that do not contain endpoint_url.
Setup phase: bind your local machine to EdgeCron
Admin Dashboard
Generate CLI Debug Token
Choose the App, forwarding scope, and expiration under API Key Management -> CLI Debug Tokens.
Developer Machine
Log in and listen
Use the token to log in. The selected local port remains available as a fallback for replay and older gateway payloads.
CLI Gateway
Create Debug Session
Gateway opens the WebSocket session and stores the App or Endpoint binding in Redis.
Delivery phase: how a real Delivery Attempt runs from your machine
EdgeCron Worker
Execute Task Run
A Schedule, Event, or manual Task creates work for a Delivery Attempt.
CLI Hook
Check online binding
Endpoint-specific sessions are matched first, then App-scoped sessions are used as fallback.
CLI Gateway
Push request to CLI
Gateway sends the complete Endpoint URL, method, headers, body, and timeout to the local CLI over WebSocket.
Developer Machine
Request the Endpoint
The CLI requests the original Endpoint URL from your machine, whether the target is public or localhost.
Delivery Result
Write back attempt result
The local status code, response body, duration, or error is written back to the Delivery Attempt.
EdgeCron Worker
Execute Task Run
A Schedule, Event, or manual Task creates work for a Delivery Attempt.
CLI Hook
Check online binding
Endpoint-specific sessions are matched first, then App-scoped sessions are used as fallback.
CLI Gateway
Push request to CLI
Gateway sends the complete Endpoint URL, method, headers, body, and timeout to the local CLI over WebSocket.
Developer Machine
Request the Endpoint
The CLI requests the original Endpoint URL from your machine, whether the target is public or localhost.
Delivery Result
Write back attempt result
The local status code, response body, duration, or error is written back to the Delivery Attempt.
When CLI does not match
If the CLI is offline, the Debug Token is expired or revoked, the forwarding scope does not match, or the CLI does not respond in time, EdgeCron falls back to the normal HTTP delivery path and continues to call the original Endpoint URL.
How it works
The full flow is:
- Generate a
CLI Debug Tokenin the admin dashboard. - Run
edgecron-cli login --token ...oredgecron-cli listen --token ...locally. - The CLI logs in to CLI Gateway, creates a Debug Session, and keeps a WebSocket connection open.
- When an EdgeCron Worker executes a Task Run, it checks whether the App or Endpoint has an online CLI Session.
- If there is a match, the Worker sends the complete Endpoint URL and request through Gateway to the CLI, and the CLI requests that URL from your machine.
- The HTTP status, response body, and duration are written back to the Delivery Attempt.
If the CLI is offline, the Debug Token is revoked, the request does not match the forwarding scope, or the CLI does not respond in time, EdgeCron falls back to the normal HTTP delivery path.
A match depends on the scope you selected when generating the Debug Token: App scope intercepts Delivery Attempts for every Endpoint under that App, while Endpoint scope only intercepts the selected Endpoints. The Endpoint URL can be public or local. The request is initiated by the CLI process on your machine.
For live deliveries, the Endpoint URL is authoritative. The fallback port does not replace a live Endpoint URL:
| Endpoint URL | CLI fallback port | Request made by CLI |
|---|---|---|
https://www.baidu.com | 3000 | https://www.baidu.com/ |
https://www.baidu.com/search?q=edgecron | 3000 | https://www.baidu.com/search?q=edgecron |
http://127.0.0.1:7749/ping | 3000 | http://127.0.0.1:7749/ping |
No endpoint_url in a replay or legacy payload | 3000 | http://127.0.0.1:3000/<request-path> |
Core, CLI Gateway, and CLI must all include the v0.1.2 relay contract for live Endpoint URL forwarding. If only the CLI binary is updated while Core or Gateway still uses the older payload, the CLI cannot recover the missing host and port and will use the fallback target.
Reliability behavior
CLI Gateway registers each pending request before pushing it to the WebSocket session, so very fast local responses are not dropped if the CLI answers immediately. When the CLI does not answer before the delivery timeout, the request is marked with a CLI timeout and EdgeCron falls back to the normal HTTP delivery path.
Closing a CLI Session is also explicit: if Gateway cannot close the session, the API returns an error instead of reporting success. This keeps the admin dashboard, Gateway, Redis session state, and local CLI behavior easier to reason about during debugging.
Prerequisites
Before you start, make sure:
- You have an EdgeCron App and can sign in to the admin dashboard.
- You have created at least one Endpoint. For example,
https://example.com/webhooks/edgecronis requested from your machine with that complete URL. - A localhost URL such as
http://127.0.0.1:7749/pingcan be used for CLI-only local debugging. Normal cloud delivery to loopback or private addresses is blocked by SSRF protection. - Public Endpoint URLs must be reachable from your machine. Local Endpoint URLs require the corresponding local service and port to be listening.
- Your operator has enabled CLI Gateway and enabled CLI Hook in EdgeCron Core. Self-hosted operators should also review the deployment checklist at the end of this page.
Do not validate CLI forwarding with the Endpoint test button
The Endpoint test button in the admin dashboard is sent directly by the admin server to the Endpoint URL. It does not go through the EdgeCron Worker CLI Hook. To validate CLI forwarding, create a Task Run, publish an Event, or wait for a Schedule trigger.
1. Download and install the CLI
Use the CLI download entry provided by your admin dashboard when it is available, and choose the package for your operating system. If your deployment has not exposed that entry yet, use the CLI binary distributed by your team.
Current package names use this format:
edgecron-cli_<version>_<os>_<arch>For example, release v0.1.3 can be published under /downloads/edgecron-cli/v0.1.3/:
| Platform | CPU | Package |
|---|---|---|
| macOS | Apple Silicon | edgecron-cli_0.1.3_darwin_arm64.tar.gz |
| macOS | Intel | edgecron-cli_0.1.3_darwin_amd64.tar.gz |
| Linux | x86_64 | edgecron-cli_0.1.3_linux_amd64.tar.gz |
| Linux | ARM64 | edgecron-cli_0.1.3_linux_arm64.tar.gz |
| Windows | x64 | edgecron-cli_0.1.3_windows_amd64.zip |
| Checksums | SHA-256 | checksums.txt |
If you are not sure which CPU you have:
uname -mUse arm64 for Apple Silicon Macs and ARM servers, and amd64 for Intel/AMD x86_64 machines.
macOS
Download, verify, and install:
curl -LO https://docs.edgecron.com/downloads/edgecron-cli/v0.1.3/edgecron-cli_0.1.3_darwin_arm64.tar.gz
curl -LO https://docs.edgecron.com/downloads/edgecron-cli/v0.1.3/checksums.txt
grep 'edgecron-cli_0.1.3_darwin_arm64.tar.gz' checksums.txt | shasum -a 256 -c -
tar -xzf edgecron-cli_0.1.3_darwin_arm64.tar.gz
cd edgecron-cli_0.1.3_darwin_arm64
chmod +x edgecron-cli
./edgecron-cli versionMove it into your PATH if you want to run it from any directory:
sudo mv edgecron-cli /usr/local/bin/edgecron-cli
edgecron-cli versionmacOS may show a security warning for a newly downloaded or unsigned CLI. Prefer verifying checksums.txt first. If Gatekeeper blocks the first run, open System Settings -> Privacy & Security, allow the blocked edgecron-cli, then run the command again. In managed company devices, ask your IT administrator to allow the binary instead of bypassing policy.
Linux
Download the package that matches your CPU:
curl -LO https://docs.edgecron.com/downloads/edgecron-cli/v0.1.3/edgecron-cli_0.1.3_linux_amd64.tar.gz
curl -LO https://docs.edgecron.com/downloads/edgecron-cli/v0.1.3/checksums.txt
grep 'edgecron-cli_0.1.3_linux_amd64.tar.gz' checksums.txt | shasum -a 256 -c -
tar -xzf edgecron-cli_0.1.3_linux_amd64.tar.gz
cd edgecron-cli_0.1.3_linux_amd64
chmod +x edgecron-cli
./edgecron-cli versionInstall it into a user-writable PATH directory:
mkdir -p ~/.local/bin
mv edgecron-cli ~/.local/bin/edgecron-cli
edgecron-cli versionIf edgecron-cli is not found, add ~/.local/bin to your shell PATH.
Windows
Download edgecron-cli_0.1.3_windows_amd64.zip, extract it, then run:
.\edgecron-cli.exe versionTo verify the downloaded file in PowerShell:
Get-FileHash .\edgecron-cli_0.1.3_windows_amd64.zip -Algorithm SHA256Compare the output with checksums.txt.
Windows SmartScreen or antivirus tools may warn about newly published command-line binaries, especially before the file has reputation history. Download only from your EdgeCron docs or admin dashboard, verify the SHA-256 checksum, and choose More info -> Run anyway only when your organization allows it. In locked-down environments, ask IT to allow-list edgecron-cli.exe.
Build from source
For source deployments or internal development, build it from the repository:
cd cli
make build
./edgecron-cli version2. Start a local callback service when needed
Skip this section when you are testing a public Endpoint URL. For a localhost Endpoint, the following Node.js example has no third-party dependencies. It accepts any path, prints the request, and returns 200.
// server.mjs
import http from "node:http";
const server = http.createServer(async (req, res) => {
const chunks = [];
for await (const chunk of req) chunks.push(chunk);
const body = Buffer.concat(chunks).toString("utf8");
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
console.log("x-edgecron-request-id:", req.headers["x-edgecron-request-id"]);
console.log("body:", body);
res.setHeader("Content-Type", "application/json");
res.end(JSON.stringify({ ok: true, received_at: new Date().toISOString() }));
});
server.listen(3000, "127.0.0.1", () => {
console.log("local webhook listening on http://127.0.0.1:3000");
});Start it:
node server.mjsTest the local service first:
curl -X POST 'http://127.0.0.1:3000/webhooks/edgecron' \
-H 'Content-Type: application/json' \
--data '{"hello":"local"}'Configure the EdgeCron Endpoint with that complete local URL, for example http://127.0.0.1:3000/webhooks/edgecron. If you already have a local application endpoint, use its actual port and path instead.
3. Generate a Debug Token in the admin dashboard
In the admin dashboard:
- Open
API Key Management. - Switch to the
CLI Debug Tokenstab. - Click
Generate Debug Token. - Select the App. Regular users usually see only their own App; super admins should choose the target App explicitly.
- Enter a clear name, such as
local debug - billing webhook. - Choose a forwarding scope.
- Set an expiration.
- Copy the Token immediately after it is created. The plaintext Token is not shown again after the dialog is closed.
Choosing a forwarding scope
Forward all endpoints to local is the default UI option and the easiest choice for the first run. While the CLI is online, all Endpoint deliveries under the selected App are routed through your CLI. Each Endpoint keeps its configured URL. You do not need to select any Endpoint.
Forward selected endpoints to local is stricter. Once you choose it, the Endpoint selector becomes required. Only selected Endpoints are routed through your CLI; all other Endpoints continue unaffected.
If you see a historical Login Test Only Token in the list, it is only for validating the CLI login flow and does not intercept or forward Delivery Attempts.
Recommended practice
For the first integration test, use a test App with the default App scope. If multiple people share the same App, or the App contains production Endpoints, use Endpoint scope and keep the expiration short.
4. Log in to the CLI
The recommended flow is to log in first and save local config:
./edgecron-cli login --token edc_dbg_your_debug_tokenAfter a successful login, the CLI stores a short-lived Gateway login token locally. Default config locations:
macOS/Linux: ~/.edgecron/config.yaml
Windows: %APPDATA%\edgecron\config.yamlFor self-hosted deployments where Gateway is not at the default endpoint, pass the endpoint:
./edgecron-cli login \
--token edc_dbg_your_debug_token \
--endpoint https://cli-gateway.your-edgecron.example.comFor local integration, the CLI does not guess your local Gateway. By default it connects to the production Gateway at https://cli-gateway.edgecron.com. Point it to your local Gateway explicitly:
./edgecron-cli --endpoint http://127.0.0.1:7750If you run the interactive onboarding from source:
cd cli
go run main.go --endpoint http://127.0.0.1:7750You can also use the environment variable:
EDGECRON_ENDPOINT=http://127.0.0.1:7750 go run main.goYou can also start a one-time session without saving login state:
./edgecron-cli listen --token edc_dbg_your_debug_token --port 3000Add --save if you want that one-time command to persist the login config:
./edgecron-cli listen --token edc_dbg_your_debug_token --port 3000 --saveWhen you launch edgecron-cli without a subcommand, the interactive flow asks for a Debug Token when needed and then creates the online CLI Session immediately. It does not wait for Enter or for fallback-port input. The configured fallback address is only used by replay and legacy gateway messages.
5. Start listening
After login, start the CLI session:
./edgecron-cli listen --port 3000 --name billing-localOutput like this means the session is connected:
Connected to EdgeCron CLI Gateway
Session: dbg_sess_xxx
Fallback Target: http://127.0.0.1:3000
Waiting for requests...Common flags:
| Flag | Purpose |
|---|---|
--port 3000 | Fallback port for replay and older gateway payloads. Defaults to default_port in config. |
--host 127.0.0.1 | Fallback host for replay and older gateway payloads. Defaults to 127.0.0.1. |
--name billing-local | Human-readable Session name for the admin dashboard. |
--path-prefix /api | Prepends a path prefix. If the Endpoint path is /webhooks/edgecron, the request path becomes /api/webhooks/edgecron. |
--header 'X-Debug:true' | Adds an extra header to requests made by the CLI. |
--timeout 15s | CLI request timeout, capped at 60 seconds. |
The CLI adds these headers to requests:
X-EdgeCron-Debug: true
X-EdgeCron-Session-ID: dbg_sess_xxx
X-EdgeCron-Request-ID: req_xxx6. Trigger a real delivery
The CLI receives Delivery Attempts executed by EdgeCron Workers. Use any of these paths:
- In the admin dashboard, open
Tasksand create an immediate Task Run for an Endpoint covered by your Debug Token scope. - Open
Eventsand publish an Event that matches the Endpoint subscription rules. - Create or wait for a Schedule trigger.
- Use the public API or an SDK to create a Task Run or publish an Event.
Example: if the Endpoint URL is https://www.baidu.com and your Debug Token scope matches that Endpoint or its App, the Delivery Attempt is sent through CLI Gateway and the CLI requests https://www.baidu.com/ from your machine. If the Endpoint URL is http://127.0.0.1:7749/ping, the CLI requests that exact local URL even when its fallback port is 3000. If the Debug Token does not match that Endpoint, or the CLI is offline, EdgeCron follows the normal cloud delivery path; public URLs are called by Core, while loopback/private URLs are rejected by SSRF protection.
When a request arrives, the CLI prints it:
POST /webhooks/edgecron [req_abc123]
← 200 OK 12msThe Endpoint receives the payload and X-EdgeCron-Request-ID. If it returns 2xx, the Delivery Attempt is marked successful. If it returns 4xx, 5xx, or the CLI request fails, EdgeCron writes back the failure result and continues to follow the Endpoint retry policy.
7. Inspect sessions and request records
Open CLI Debug Sessions in the admin dashboard to view:
- Current and historical Debug Sessions.
- Session status, fallback address, connected time, last heartbeat, and expiration.
- CLI request records, including request ID, Endpoint, status code, duration, and error.
- Manual Session close action when needed.
In API Key Management under the CLI Debug Tokens tab, you can inspect Token status, expiration, last four characters, and revoke a Token.
In Deliveries, you can inspect the final Delivery Attempt result written back by the CLI flow.
8. Replay locally
After you have logged in, replay a request to your local service with its request_id:
./edgecron-cli replay req_abc123 --port 3000Replay with a modified body:
./edgecron-cli replay req_abc123 \
--port 3000 \
--body '{"invoice_id":"inv_123","status":"paid"}'Replay with a body file:
./edgecron-cli replay req_abc123 --port 3000 --body-file payload.jsonreplay uses the current CLI process cache first. If the request is not found locally, it asks Gateway for request details. It only replays to your local service. It does not create a new Task Run and does not modify the original Delivery Attempt.
Troubleshooting
| Symptom | What to check |
|---|---|
login failed | Make sure the Token was copied completely, is not expired or revoked, the self-hosted --endpoint is correct, and Gateway is reachable. |
| CLI is connected but no local requests arrive | Trigger through Task Run, Event, or Schedule. Do not use the Endpoint test button. Check that the Debug Token App and Endpoint match, and that EdgeCron Core has cli_hook.enabled enabled. |
| Endpoint returns 404 | Confirm the Endpoint path exists, or use --path-prefix to adjust it for debugging. |
| Connection refused | Check the CLI Request Target. For localhost targets, confirm that the service is listening on the Endpoint URL port. For replay or legacy payloads, check the fallback --host and --port. |
| CLI receives no request and cloud delivery runs instead | CLI may be offline, Session may be expired, Token may be revoked, the scope may not match, or Core and Gateway may not share the same Redis instance and DB. |
| Replay cannot find the request | Use login or listen --save to persist login state. Confirm the request_id comes from a CLI debug request record, not a normal API response request_id. |
Security guidance
- A
CLI Debug Tokenis not a public API Key. It does not replaceak_xxx/sk_xxxfor/v1API calls. It is only for CLI Gateway login and local debug sessions. - The plaintext Token is shown once. Do not commit it to Git, CI logs, screenshots, or support tickets.
- Revoke the Token and close unused CLI Sessions when debugging is finished.
- App scope affects every Endpoint under the selected App. Use Endpoint scope in shared environments.
- The Endpoint receives real payloads from your machine. Treat production data according to your team's logging and data handling rules.
Publishing CLI downloads
For releases managed with the docs site, build the packages from cli/:
make release VERSION=0.1.3
make verify-releaseThen copy the release files into the docs public directory:
edgecron-docs/public/downloads/edgecron-cli/v0.1.3/Keep this directory structure:
downloads/
edgecron-cli/
v0.1.3/
edgecron-cli_0.1.3_darwin_amd64.tar.gz
edgecron-cli_0.1.3_darwin_arm64.tar.gz
edgecron-cli_0.1.3_linux_amd64.tar.gz
edgecron-cli_0.1.3_linux_arm64.tar.gz
edgecron-cli_0.1.3_windows_amd64.zip
checksums.txtBecause files under public/ are served as static assets, the docs site can expose direct download links such as:
https://docs.edgecron.com/downloads/edgecron-cli/v0.1.3/edgecron-cli_0.1.3_darwin_arm64.tar.gzThis is the simplest option while every package is under the Cloudflare Pages single-asset limit. If a package grows beyond that limit, or if you want a dedicated downloads domain, upload the same tree to Cloudflare R2 and attach a custom domain such as:
https://downloads.edgecron.com/edgecron-cli/v0.1.3/edgecron-cli_0.1.3_darwin_arm64.tar.gzFor production R2 downloads, use a custom domain instead of an r2.dev development URL, so you can manage caching, access control, and security rules from Cloudflare.
Self-hosted deployment checklist
If you operate a private or self-hosted EdgeCron deployment, confirm that:
cli-gateway/config/config.prod.ymlhas a publicwss://public_ws_urlreachable by browsers and CLI clients.cli-gatewayhasauth.allow_dev_fallbackset tofalsein production.cli-gatewayandedgecronuse the same Redis instance and Redis DB so they can share online Session bindings. Localdevconfigs should default to Redis DB0.edgecron/config/config.prod.ymlhascli_hook.enabledenabled according to your rollout plan.edgecronandcli-gatewayuse the same Redis channel settings, defaulting tocli:task:pushandcli:task:result:.- The admin dashboard, Gateway, and Core use the same
cli_debug_tokens,cli_sessions, andcli_requeststable structures.