REST API

wigolo serve turns wigolo into an HTTP daemon: a REST endpoint per tool, a machine-readable OpenAPI contract, and remote MCP transports — one process serving CLI scripts, SDKs, and multiple agents at once.

wigolo serve [--port N] [--host H] [--allow-unauthenticated]

Defaults: 127.0.0.1:3333 (override with WIGOLO_DAEMON_PORT / WIGOLO_DAEMON_HOST). Startup names every surface:

[wigolo serve] Daemon running at http://127.0.0.1:3333
[wigolo serve] Health check: curl http://127.0.0.1:3333/health
[wigolo serve] REST API: http://127.0.0.1:3333/v1  (OpenAPI: http://127.0.0.1:3333/openapi.json)
[wigolo serve] Auth: open on loopback only
[wigolo serve] MCP endpoint: http://127.0.0.1:3333/mcp (StreamableHTTP)
[wigolo serve] SSE endpoint: http://127.0.0.1:3333/sse

Endpoints

EndpointMethodWhat it is
/v1/{tool}POSTOne route per tool: search, fetch, crawl, cache, extract, find_similar, research, agent, diff, watch. Body = the tool's JSON params (tools reference); response = the tool's JSON result.
/v1/toolsGETLists all tools with descriptions and endpoints.
/healthGETLiveness + component status. Always open — no token required, safe for load balancers and container healthchecks.
/openapi.jsonGETThe OpenAPI 3.1 contract (also at /v1/openapi.json).
/mcpPOST/GET/DELETERemote MCP over StreamableHTTP — point HTTP-capable MCP clients here.
/sse + /messagesGET / POSTLegacy MCP-over-SSE transport.
/admin/reset-breakersPOSTOperator control route (resets search-engine circuit breakers). Guarded by a per-process token written owner-only to disk; used by wigolo doctor --fix.

Auth model — fail closed

  • Loopback bind (default): open. No token needed for local callers.
  • Non-loopback bind: token required. Binding to anything that isn't loopback with no token configured refuses to start unless you pass --allow-unauthenticated (or WIGOLO_SERVE_ALLOW_UNAUTHENTICATED=1) — an explicit, logged operator override.

Set the token with WIGOLO_API_TOKEN, or WIGOLO_API_TOKEN_FILE to read it from a file (the Docker/systemd secret pattern — keeps it out of process listings). With a token configured, every /v1, /openapi.json, compat-shim, and MCP request needs Authorization: Bearer <token>; /health stays open.

The MCP transport additionally rejects any request carrying a browser Origin header (CLI/MCP clients never send one) and any non-allowlisted Host — blocking token probing from web pages and DNS-rebinding attacks even in token mode.

One more remote-exposure guard: under a non-loopback bind, tool calls targeting loopback/localhost URLs are refused (a remote caller could otherwise probe services on the daemon's own box). WIGOLO_SERVE_ALLOW_LOCAL_TARGETS=1 opts back in. See self-hosting.

Resource limits

All transport policy, all env-tunable — the tool layer's own defaults are separate:

LimitDefaultOverride
Request body1 MiB (5 MiB for diff/extract)WIGOLO_SERVE_MAX_BODY_BYTES
Response deadline60s search/cache/diff/find_similar · 120s fetch/extract/watch · 300s crawl/research/agentWIGOLO_SERVE_TIMEOUT_SCALE (multiplier)
In-flight requests16WIGOLO_SERVE_MAX_CONCURRENCY
Whole-request / headers timeout120s / 60sWIGOLO_SERVE_REQUEST_TIMEOUT_MS / WIGOLO_SERVE_HEADERS_TIMEOUT_MS

Server-side param clamps (also injected into the served OpenAPI bounds, so contract and enforcement can't drift): crawl.max_pages ≤ 200, crawl.max_depth ≤ 5, agent.max_time_ms ≤ 240000, search.query array ≤ 10 variants.

Quickstart (recorded)

Start a daemon and probe it — these are real responses from wigolo serve --port 3477:

curl -s http://127.0.0.1:3477/health
{"status":"healthy","searxng":"not_configured","browsers":"ready","cache":"active","uptime_seconds":6}

(The searxng field reports the optional legacy aggregator sidecar; not_configured is the normal state on the default backend.)

curl -s -X POST http://127.0.0.1:3477/v1/search \
  -H 'Content-Type: application/json' \
  -d '{"query":"wigolo local-first web intelligence","max_results":2,"search_depth":"fast"}'
{"results":[{"title":"...","url":"https://github.com/KnockOutEZ/wigolo",
  "snippet":"wigolo runs on your machine as an MCP server ...",
  "relevance_score":0.968,
  "evidence_score":{"final":0.224,"components":{"base_rrf":0.023,"domain_quality":1,
    "lexical_alignment":0.4,"engine_consensus":2,"rare_terms":1.6}, "explanation":"..."}}],
 "engines_used":["bing","duckduckgo"], "...":"..."}

With a token:

WIGOLO_API_TOKEN=$(openssl rand -hex 32) wigolo serve --host 0.0.0.0 --port 3333
curl -s -H "Authorization: Bearer $WIGOLO_API_TOKEN" http://<host>:3333/v1/tools

OpenAPI as the machine contract

GET /openapi.json returns OpenAPI 3.1.0 (info.title: "wigolo REST API", versioned with the release — currently 0.2.0) covering every route, parameter schema, and the enforced clamps. Generate clients from it, validate against it, or hand it to an agent as the tool contract. The SDKs are drift-tested against this document.

Compat shim

WIGOLO_FIRECRAWL_COMPAT=1 enables an opt-in, experimental compatibility shim at /compat/firecrawl that accepts hosted-scraper-style requests — useful for pointing existing integrations at your own wigolo instead. It sits behind the same auth and target guards as everything else.

Error shape

Non-2xx responses carry a consistent JSON body: error (message), error_reason (stable machine code, e.g. unauthorized, host_not_allowed), and where relevant a hint naming the exact env var or flag to fix it. Degraded-but-successful tool calls stay 2xx with in-body warning/error fields — inspect those rather than relying on status codes alone.

← Docs index · Next: SDKs

Edit this page on GitHub