connect CLI
Onboard logs in minutes with @nano-rs/connect — generate edge Vector collectors, choose a transport, deploy parsers, and verify data is flowing
connect CLI
@nano-rs/connect is a zero-install CLI that points real data at your nano instance. It connects to your deployment, stands up edge Vector collectors in your environment (syslog, Windows Event Log + Sysmon, Linux journald + files), wires them to nano, deploys matching parsers, and verifies events arrive and become searchable — no MCP, no Kubernetes, no hand-written config.
npx @nano-rs/connectHow it works
connect generates Vector configuration for the edge of your network and forwards it to nano. The topology scales from a single box to a fleet:
- Agents run on endpoints and ship to an aggregator (or straight to nano for small setups).
- The aggregator is the hub — receives agents and syslog devices, forwards to nano.
Two secrets, by design. An API key talks to the nano API (verify + parser deploy); a separate ingest token (VECTOR_AUTH_TOKEN) authenticates the logs themselves. connect mints a scoped API key for you (showing the permissions first). The ingest token comes from your self-hosted .env, or from app.nano.rs → your deployment → Credentials on a managed deployment.
Prerequisites
- A running nano deployment and its URL
- Docker (only if you want
connectto run the collector for you with--run)
Step 1: Connect
npx @nano-rs/connect connect --url https://your-nano-instance.comThis authenticates (reuses your install's .env, or logs you in and mints a scoped key), then sends a test event to confirm the ingest path — auto-detecting your endpoint shape (/ingest/, a dedicated ingest-<sub> host, or the open-core :8080). The endpoint that works is saved, so later commands target a proven URL.
Step 2: Choose a transport
Every generator takes --transport native|http. Both deliver to nano; pick based on where your collector sits.
native (default) | http | |
|---|---|---|
| Wire | Vector protobuf on :6000 | NDJSON to /ingest/ on 443 |
| Encryption | TLS | HTTPS |
| Authentication | network-level, or a client certificate | ingest token on every request |
| Delivery | acknowledgements + backpressure + disk buffer | disk buffer |
| Sinks generated | one for everything | one per source_type |
Use native when the collector reaches nano over a trusted network, a VPN, a private link, or with a client certificate. You get end-to-end acknowledgements and backpressure, which matter at volume.
Use http when the collector sits on the public internet, when :6000 isn't reachable from it, or when you want every request authenticated with a credential you control:
npx @nano-rs/connect add-source --sources cisco_asa --transport httpThe ingest token is written to a .env (mode 0600) beside the generated config and read as ${VECTOR_AUTH_TOKEN} — it is never written into vector.toml. docker-compose.yml is wired to load it.
HTTP generates one sink per source_type. nano routes on the X-Source-Type request header, and Vector's HTTP sink headers are fixed per sink — so each source_type gets its own [sinks.nano_<source_type>] block. When you enable another listener in vector.toml, copy an existing sink block, point its inputs at that listener's _tag transform, and set its X-Source-Type. Without a matching sink, those events arrive as unknown.
Client certificates (mTLS)
If your deployment issues a client certificate for the native port, download it from app.nano.rs → your deployment → Credentials → Vector mTLS → Download bundle and drop the three files — ca.crt, client.crt, client.key — into the directory you run connect from. Every generator picks them up automatically:
● Transport: Vector-native + TLS → nano.example.com:6000 (client certificate from /srv/onboarding)Use --mtls-dir <dir> if they live somewhere else.
Keep the exact filenames, and keep one deployment's bundle per directory. Browsers rename repeat downloads to client (1).crt, so a downloads folder can easily end up holding bundles from several deployments — connect won't guess between them. It also checks the certificate belongs to the deployment you're onboarding and stops if it doesn't, rather than authenticating as the wrong tenant.
The certificates are copied into tls/ inside the generated bundle and referenced from /etc/vector/tls — the path docker-compose.yml mounts them at, and the one the systemd instructions tell you to copy them to. client.key is written 0600.
Step 3: Set up a collector
Pick the generator that matches what you're collecting.
Syslog devices
npx @nano-rs/connect list-sources
npx @nano-rs/connect add-source --sources cisco_asa,palo_alto --run --deploy-parserslist-sources prints every built-in source_type with its port and protocol. One listener port per source_type (so each vendor routes to the right parser) — point your firewalls and switches at <this-host>:5514 (Cisco ASA), :5515 (Palo Alto), and so on. The generated README.md lists every port.
Collecting from a vendor that isn't listed? Copy a listener block in the generated vector.toml and change its id, port, mode, and source_type.
Windows endpoint
npx @nano-rs/connect add-agent --os windows --target aggregator.internal:9000Native Windows Event Log + Sysmon collection. Copy the folder to the endpoint and run install-agent.ps1 (elevated) — it verifies the Vector MSI signature and registers the service.
Linux endpoint
npx @nano-rs/connect add-agent --os linux --target aggregator.internal:9000journald + Sysmon for Linux (auto-tagged) + any log files you specify. Install via the generated systemd unit.
Aggregator
npx @nano-rs/connect add-aggregator --runThe hub that fans endpoint agents (:9000) and syslog devices into nano. Point your agents at <this-host>:9000.
--transport applies to the nano uplink. The agent-to-aggregator hop stays on your own network, so set the transport on the aggregator (or on an agent using --to-nano), not on an agent pointed at an aggregator.
--run pulls the Vector image and starts the collector right there, then waits for it to report healthy. --deploy-parsers auto-deploys the matching community parser.
Step 4: Verify
npx @nano-rs/connect verify --source cisco_asa◇ 142 cisco_asa event(s) searchable in the last 15m — normalized ✓verify reports arrival and normalization separately, because they're different things:
◇ 142 cisco_asa event(s) searchable in the last 15m — NOT normalized
▲ These are landing in the generic lane (no parser deployed for cisco_asa), so they're
searchable as raw logs but carry no UDM fields — detections and dashboards that key on
UDM won't match.If you see that, your collector is working and a parser is what's missing.
A third state is worth knowing, because it looks like the others but needs a different fix:
◇ 142 cisco_asa event(s) searchable in the last 15m — parser ran but FAILED
▲ A parser for cisco_asa is deployed and claiming these events, but can't read
them: Could not parse ASA message ID patternThat means a parser is deployed and running, but the events aren't in the shape it expects — a format mismatch, not a missing parser. Re-deploying won't help; check what the collector is sending. Syslog parsers in particular match the raw wire line (<pri>timestamp host %VENDOR-…), so anything that pre-parses or re-encodes the event before it reaches nano will defeat them.
Parsers
When you onboard a source, connect tells you whether nano already parses it, whether a community parser is available (and offers to deploy it), or whether there's none yet.
That check reads your instance's parser catalog, so it's only as complete as the catalog is. An instance with no parser repository configured reports "no parser yet" for every source — which looks like nano doesn't support your log type when it simply hasn't pulled the list:
npx @nano-rs/connect sync-parsersThis registers the official nano-rs/parsers repository if none is configured (it asks first — pointing your instance at a git source is a separate permission), syncs it, and reports how many parsers are available. Worth running on a fresh instance, or any time you want to pick up newly contributed parsers.
A missing parser never blocks onboarding. Data still flows and is searchable as generic logs — a parser just normalizes it into UDM fields for better detection and dashboards. Build one in the Parser Editor, with the nano-investigator MCP, or contribute to nano-rs/parsers.
Deploying a community parser creates a log source, publishes the routing configuration, and activates it — so the API key needs permission to create log sources, edit source configs, and deploy them. Syncing the catalog needs sync, and registering a repository needs manage. connect requests these when it mints a key; if your account can't grant them it falls back to a read-only key and tells you which step is unavailable.
A log source can exist without an active parser. Importing and activating are two steps: the import creates the log source (so it appears under Log Sources and looks onboarded), and only activation makes a parser run. If activation doesn't complete, connect says so and points you at Log Sources → your source → Deploy — until then events keep landing as generic logs with no UDM fields.
Parsing applies to newly ingested events. Deploying a parser doesn't re-parse data already stored, so send fresh data before checking with verify. A mixed result (3 normalized, 5 generic) usually means the parser was deployed part-way through the window you're searching.
Command reference
| Command | Purpose |
|---|---|
connect | Connect + authenticate, send a test event |
add-source | Syslog collector (one port per source_type) |
add-agent --os windows|linux | Endpoint agent (Event Log/Sysmon, or journald/files) |
add-aggregator | Aggregator pool |
verify --source <type> | Check a source_type is arriving + normalized |
sync-parsers | Refresh the community parser catalog |
list-sources | List the built-in syslog source_types |
| Flag | Purpose |
|---|---|
--transport native|http | How the collector reaches nano |
--mtls-dir <dir> | Where to find the client-certificate bundle (default: the current directory) |
--ingest-url <url> / --ingest-token <token> | Override what --transport http uses |
--sources a,b | Which syslog source_types to collect |
--target host:port / --to-nano | Where an agent ships |
--run | Pull the image and start the collector here |
--deploy-parsers | Auto-deploy matching community parsers |
--url / --api-key / --env-file | Authentication |
--non-interactive | For CI and scripts |
Upgrading from an older collector
Configs generated before 0.2.0 are not forward-compatible in one respect: syslog listeners used Vector's syslog source, which parses the envelope and forwards only the message body — stripping the vendor tag that parsers match on. Those collectors ingest fine but never normalize.
If you generated a syslog collector before 0.2.0, re-generate it:
npx @nano-rs/connect@latest add-source --sources cisco_asa --transport httpthen restart the collector with the new vector.toml. Endpoint agents are unaffected. Check the result with verify — it should report normalized ✓ rather than parser ran but FAILED.
Next steps
- On-premise collection — the manual Vector aggregator setup
connectautomates - Routing model — how source_type drives parser selection