nano SIEM
Agents & MCPInvestigator

Build parsers

Author, validate, test, and deploy log-source parsers (Vector VRL) over MCP with the build_parser prompt — no web UI

Build parsers

Beyond reading the SIEM, nano-investigator can build the data layer underneath it. A set of parser tools lets the agent author a log-source parser — the Vector VRL that normalizes a raw log into nano's Unified Data Model — and take it all the way to live, without leaving the chat. The agent writes the VRL, the server validates and tests it against a real sample, then saves and deploys it.

This is one of two ways to author a parser in the OSS build, and it's the interactive one: you work against a live tenant over MCP, and the server validates, tests, and deploys for you. The other is the version-controlled path in Authoring parsers — draft a parser.yaml against the nano-rs/parsers repo, validate it with the vector vrl CLI, and ship it by PR or UI import. Use that one when a parser should be reviewed and version-controlled; use this one to stand a parser up quickly on a running deployment. (nano's Enterprise build adds an AI parser wizard on top; these tools give any coding agent the same authoring discipline via the VRL reference and the validate-first loop, with no AI-credit or Enterprise dependency.)

The build_parser prompt

build_parser takes source_type (required) and sample_log (optional but strongly recommended). It scripts a validate-first loop so the agent never deploys VRL it hasn't compiled and tested:

  1. Read the nanosiem://reference/vrl-parsers resource and the UDM schema
  2. list_log_sources — don't duplicate an existing source_type
  3. Draft a generic parser for the whole source, not just the sample
  4. validate_vrl — compile-check; fix every diagnostic and re-run until valid
  5. test_parse_sample — run the VRL against the sample, inspect the udm.* output
  6. create_log_source — save as a draft (validated, not deployed)
  7. deploy_log_source — push the config to Vector
  8. get_log_source_health — confirm events are actually flowing

The agent presents the VRL and the test output before saving, and confirms before deploying, so you stay in control.

The VRL reference

The nanosiem://reference/vrl-parsers resource is what makes hand-authored VRL reliable. It encodes the same guardrails nano's validator enforces:

  • The input/output contract — read .message, normalize .udm.timestamp to %Y-%m-%d %H:%M:%S, set .udm.event_type from the data, preserve the raw log
  • The rules the validator hard-rejects — named-capture regex ((?P<name>...)), ?? only on fallible calls (E651), else on the same line (E203), define-before-use
  • The forbidden functions — get_env_var, get_hostname, http_request, dns_lookup, reverse_dns are blocked at validation and stripped from the runtime registry; VRL is capped at 1 MB
  • Copy-paste skeletons for JSON and regex/line-oriented sources

Point the agent at it before it writes anything: "read the vrl-parsers reference, then write a parser for these logs."

Validate and test before saving

Two tools run a parser without touching saved state, and the loop between them is where most of the work happens:

  • validate_vrl (vrl_code) compiles the VRL and returns { valid, errors, diagnostics }. Diagnostics carry line/column and a code (like E651 or E203) so the agent can fix the exact spot.
  • test_parse_sample (vrl_code, sample_log) runs the VRL against one raw line and returns the parsed output plus an extracted_field_count. An empty or near-empty udm means the parser isn't actually extracting — keep iterating.

For a source_type that's already ingesting, test_parse_live pulls real recent events from ClickHouse and parses them with both the new and the currently deployed VRL, side by side — useful when you're refining a parser rather than writing a new one.

> build a parser for source_type "acme_fw". sample:
  ts=2026-06-01T10:15:00Z src=10.1.1.5 dst=8.8.8.8 act=deny proto=udp dpt=53

Running build_parser (source_type=acme_fw)...

Reading nanosiem://reference/vrl-parsers and the UDM schema.
list_log_sources: no existing parser for acme_fw. Drafting.

validate_vrl: valid=false — E651 at 7:34 (`??` on to_string).
Fixed. validate_vrl: valid=true.

test_parse_sample: success=true, extracted_field_count=6
  udm.timestamp   = "2026-06-01 10:15:00"
  udm.src_ip      = "10.1.1.5"
  udm.dest_ip     = "8.8.8.8"
  udm.dest_port   = 53
  udm.protocol    = "udp"
  udm.event_type  = "deny"

Output looks right. Save this as a draft for acme_fw? (won't deploy yet)

Save, then deploy

Saving and deploying are deliberately separate, the same as the web UI.

create_log_source (name, source_type, parser_vrl) saves a draft: the server validates it and stores it, but it is not live. update_log_source edits an existing parser the same way — editing VRL never auto-deploys.

deploy_log_source (id) writes the Vector config and triggers a reload. undeploy_log_source takes it back offline.

Wire the routing

A deployed parser only sees events that a routing rule sends it. The source-configuration tools cover that ingress layer:

  • list_source_config_types lists the transport drivers (HTTP, Kafka, AWS S3, GCP Pub/Sub, Splunk HEC, Vector) with their match_field presets.
  • list_source_configs lists the configured transports.
  • create_routing_rule (source_config_id, match_field, match_type, target_source_type) maps incoming events to a parser's source_type.
  • check_rule_reachability verifies, before you create a rule, that the source config is enabled and deployed, that a parser exists for the target source_type, and (for Kafka) that a broker is reachable.

For the common HTTP/routed case the sender sets the X-Source-Type header, so a parser whose source_type matches the header is reachable as soon as it's deployed — no extra rule needed.

Start from a prebuilt parser

You don't always start from scratch. nano can pull parsers from an upstream library (such as nano-rs/parsers):

  • list_parser_repositories lists connected repositories and their sync status.
  • sync_parser_repository (repository_id) refreshes the local cache from the upstream repo.
  • list_repository_parsers (repository_id) browses the available parsers.
  • import_parser (repository_id, path) imports one as a draft log source — linked (tracks upstream updates) by default, or forked for a detached copy. Then deploy it like any other.

What's next

On this page

On this page