Skip to content

Quick start

This guide takes you from nothing to a working pair of services, with a first pipeline triggered by a real webhook. VectorStep orchestrates: it receives webhooks, resolves the matching pipeline, and gates each step’s result before continuing. The Gateway executes: it owns the full agentic loop for a step (LLM calls, MCP tool execution, multi-turn conversation) and hands VectorStep back one clean result — never the intermediate tool calls. Start the Gateway first, since VectorStep calls out to it.

  • Docker, with Compose v2 — that ships with current Docker Desktop and Docker Engine. Nothing else: no Python, no git, no source checkout.
  • An LLM provider API key (Anthropic, OpenRouter, Google, Azure OpenAI, or a local Ollama — the Gateway supports all of them).
  • Works on macOS, Linux, and Windows via Docker Desktop.

Local evaluation runs on SQLite with zero extra infrastructure; PostgreSQL is recommended for production.

Terminal window
export ANTHROPIC_API_KEY=sk-ant-...
curl -sSL https://raw.githubusercontent.com/bantex01/VectorStep-Dist/main/install.sh | bash

That pulls the published images, starts VectorStep and the Gateway, and puts everything in ~/.vectorstep/. When it finishes, the UI is at http://localhost:8000/ui/ — it’ll prompt you for a login token; see below for where to find it.

The installer picks up ANTHROPIC_API_KEY from your environment if you export it first, as above. If you’d rather not, add it to ~/.vectorstep/.env afterwards and re-run — re-running is always safe, and never overwrites your config or .env.

Running the Gateway elsewhere, or driving VectorStep with OpenClaw instead? Add --service-only. Want PostgreSQL instead of the SQLite default? Add --postgres — see Deployment for what it sets up:

Terminal window
curl -sSL https://raw.githubusercontent.com/bantex01/VectorStep-Dist/main/install.sh | bash -s -- --service-only

VectorStep and the Gateway split the work: VectorStep orchestrates — it receives webhooks, resolves the matching pipeline, and gates each step’s result before continuing. The Gateway executes — it owns the full agentic loop for a step (LLM calls, MCP tool execution, multi-turn conversation) and hands VectorStep back one clean result, never the intermediate tool calls.

The Gateway mints two tokens for itself on first boot — an invoke token, which VectorStep needs in order to call it, and a separate admin token for authoring agents. The installer reads the invoke token out and writes it to ~/.vectorstep/.env for you, so the pair comes up already authenticated — there’s nothing to copy and paste. The admin token is printed at the end of the install for you to save if you’ll be authoring agents yourself.

VectorStep mints its own, separate token on first boot too — don’t confuse it with the Gateway admin token above. Every route requires a credential (see Security), including the UI, and this is what you log in with. install.sh prints it at the end as “VectorStep admin token (needed to log into the UI)” — if you missed it, it’s saved in ~/.vectorstep/.env as VECTORSTEP_ADMIN_TOKEN:

Terminal window
grep VECTORSTEP_ADMIN_TOKEN ~/.vectorstep/.env

Paste that value into the login prompt at http://localhost:8000/ui/.

Check both are healthy:

Terminal window
cd ~/.vectorstep
docker compose ps
curl -s localhost:8000/health
docker compose exec gateway curl -s localhost:18780/health

The Gateway publishes no host port by default — vectorstep reaches it over the compose network, and that’s all this guide needs, so the second check runs curl from inside the container rather than localhost:18780 from the host. See Reaching the Gateway from the host if you need host access, e.g. for a Gateway MCP client.

The installer seeds sample agents into ~/.vectorstep/agents/. The one this guide uses is generic-pipeline-step — it needs no MCP tools, just a model, so it runs with nothing more than your API key.

Terminal window
ls ~/.vectorstep/agents/
cat ~/.vectorstep/agents/generic-pipeline-step/agent.yaml

Agent directories are read from the host, so you can edit them with a normal editor and the Gateway picks them up. One rule: agent.yaml’s name: field must match its containing directory exactly, or the Gateway skips it with a logged error.

The sample defaults to an Anthropic model, which is why that’s the key you exported. The Gateway also supports OpenRouter, Google, Azure OpenAI, and Ollama — see Providers for every model string format. Once you’re past this guide, Tutorials walks through writing a real agent from scratch.

Using OpenRouter (or another non-Anthropic provider) instead? Three things need to change from the defaults above — a provider key alone isn’t picked up automatically:

  1. Add your key to ~/.vectorstep/.env, e.g. OPENROUTER_API_KEY=sk-or-... (the installer doesn’t seed this line for you — add it yourself).
  2. Add a matching block under providers: in ~/.vectorstep/config/gateway.yaml — the shipped default only defines anthropic:
    providers:
    openrouter:
    api_key: ${OPENROUTER_API_KEY}
    base_url: https://openrouter.ai/api/v1
  3. Point the model: field in ~/.vectorstep/agents/generic-pipeline-step/agent.yaml — the same file you cat’d above — at that provider, e.g. openrouter/deepseek/deepseek-chat. See Providers for the full prefix list and every supported model string format.

Then apply it — docker compose up -d gateway from ~/.vectorstep/, not docker compose restart gateway. restart reuses the container’s existing environment as-is, so a key you just added to .env stays invisible to the process; up -d recreates the container against the current .env and config/gateway.yaml, so it’s the one that actually picks up both changes.

Pipelines are YAML files in ~/.vectorstep/pipelines/; reusable steps live in ~/.vectorstep/steps/. Both are ordinary host directories mounted into the container, so edit them with whatever you normally use. The installer seeds both with real production samples wired to OpenClaw and external tools like Jira and Confluence — worth exploring later, but not a fit for this walkthrough. Create the two files below instead: a complete pipeline built for the agent from step 2, needing no MCP tools, since generic-pipeline-step reasons from the alert payload alone.

This step is deliberately named quickstart-triage, not first-line-triage — the installer’s seeded samples already include a different first-line-triage step (OpenClaw-based, needs Confluence/Jira). Using that name here would silently overwrite the seeded one instead of creating something new.

Create steps/quickstart-triage.yaml:

name: quickstart-triage
description: First-line triage for a critical alert — no MCP tools required.
executor: gateway
executor_config:
agent: generic-pipeline-step
session_key: "agent:generic-pipeline-step:{{pipeline_run_id}}:{{current_step}}"
confidence_threshold: 0.60
on_low_confidence: escalate
prompt_template: |
A {{severity}} alert fired for {{labels.service}} in {{labels.environment}}.
Summary: {{summary}}
Summarise what's happening. Set confidence based on how clearly the alert
data explains the problem — not on how serious it is.
Return JSON only, no other text:
{
"confidence": 0.0,
"summary": "One sentence: what's happening and how serious",
"next_step_context": "Focused brief for whatever handles this next",
"reasoning": {
"supports": "Evidence that makes this alert credible",
"contradicts": "Evidence that suggests noise or a false positive",
"assumptions": "What you're assuming in the absence of data"
}
}

Create pipelines/alert-triage.yaml:

name: alert-triage
description: First-line triage for critical alerts
trigger:
match: { source: alertmanager, severity: critical }
dedup:
enabled: false
context_template:
include:
- severity
- summary
steps:
- name: triage
use: quickstart-triage # reusable step from your step library
executor: gateway
executor_config:
agent: generic-pipeline-step
confidence_threshold: 0.75
on_low_confidence: escalate # below the bar, a human sees it instead

context_template.include is what makes {{severity}} and {{summary}} resolve to real values in the prompt above — only fields listed here are pulled from the incoming alert; everything else you might reference (like {{labels.service}}) is available without it. Leave a field out and it silently renders as an empty string rather than erroring, so it’s easy to miss if you add a new {{...}} reference later and forget to list it here.

dedup.enabled: false here is a quick-start convenience, not a general recommendation — the bundled test fixture has no unique fingerprint, so every replay hashes identical and would otherwise hit the (correct, and normally desirable) service-wide dedup window. See Idempotency & deduplication for how it works against real alert traffic.

Reload without restarting. Every VectorStep route requires a bearer token (see Security) — /reload needs the admin token, the same VECTORSTEP_ADMIN_TOKEN you logged into the UI with:

Terminal window
curl -X POST http://localhost:8000/reload \
-H "Authorization: Bearer $(grep VECTORSTEP_ADMIN_TOKEN ~/.vectorstep/.env | cut -d= -f2)"
# → {"status": "reloaded", "pipelines_loaded": 1}

Send a test webhook using one of the bundled fixtures. This one needs the webhook token instead — VECTORSTEP_WEBHOOK_TOKEN in the same .env file. The admin token won’t work here: /webhook accepts only a token scoped specifically to webhook, admin included, and returns 403 for anything else, including the admin token:

Terminal window
curl -X POST "http://localhost:8000/webhook?source=alertmanager&allow_testing=true" \
-H "Authorization: Bearer $(grep VECTORSTEP_WEBHOOK_TOKEN ~/.vectorstep/.env | cut -d= -f2)" \
-H "Content-Type: application/json" \
-d @webhooks/alertmanager_critical.json
# → {"status": "accepted", "run_id": "<uuid>"}

New pipelines default to stage: testing — fully executable, but inert to real ingestion traffic until you deliberately opt in with allow_testing=true (or promote the pipeline itself to stage: production later). See Pipeline stages for what each stage actually gates.

Open http://localhost:8000/ui/ — the dashboard shows the run live. Click into it for the full run log: every step’s prompt, output, confidence score, and the Trust panel explaining exactly how each gating decision was made.

Don’t expect a solved incident — expect an honest escalation, and that’s the point. The triage step should show a badge reading escalated, with confidence below the pipeline’s confidence_threshold: 0.75, and a summary that references the real alert content now flowing through {{severity}} and {{summary}} — something like “A critical alert fired for payments-api: error rate exceeded 5% for 5 minutes. No deeper diagnostic data (logs, traces, upstream dependencies) is available to confirm a root cause or rule out a false positive.”

That’s the agent being honest, not broken: generic-pipeline-step has tools: [] — no MCP tools — so even with a concrete metric breach in hand, it has no way to independently verify anything beyond what the alert itself states. It correctly recognises it can’t diagnose the actual cause from that alone, scores its own confidence accordingly, and the pipeline’s on_low_confidence: escalate gate does exactly what it’s supposed to: refuse to let an under-verified assessment pass as if it were a real finding. Expand REASONING on the step to see the model’s own supports/contradicts/assumptions breakdown behind that score.

One thing that can look contradictory at first: the step may show proceed: true right next to an escalated badge. Those are two different signals — proceed is the agent’s own opinion (from its soul.md) about whether its instructions call for stopping outright; the escalation itself is a separate, pipeline-level decision driven purely by confidence falling below the threshold. An agent can think there’s no reason to abort and still get escalated for a human to check, because it didn’t feel confident about what it found.

Giving this same agent real tools — so its low confidence turns into a grounded, higher one — is exactly what Tutorial: build your first agent does next.

You can also live-tail from the run detail page, or query the API directly — back to the admin token here, same as /reload:

Terminal window
ADMIN_TOKEN=$(grep VECTORSTEP_ADMIN_TOKEN ~/.vectorstep/.env | cut -d= -f2)
curl http://localhost:8000/runs -H "Authorization: Bearer $ADMIN_TOKEN" # newest first
curl http://localhost:8000/runs/<run_id> -H "Authorization: Bearer $ADMIN_TOKEN" # full detail with per-step confidence

If any of this — the Gateway, agents, MCP tools, confidence gating — is new to you, don’t jump straight to the reference docs below. Go to Tutorials next: it builds a real agent from scratch, wires it to two MCP servers, and then turns on gating one signal at a time, hands-on. It builds directly on the pipeline you just triggered.

Once you’re comfortable with the mechanics:

  • How confidence and calibration work — the trust vector (S/V/G/D) and every knob that affects it. Read this before turning on any enforcement.
  • Pipeline schema — the full YAML reference: verifiers, grounding, parallel groups, fan-out, flow control.
  • Verifiers — adding a second opinion to a step, and when to use critic vs independent mode.