Execution server
langoost server runs Langoost as a persistent daemon that executes scripts
over HTTP. The process stays warm and caches compiled modules, so there’s no
per-request cold start; each execution still runs in its own isolated VM.
This is different from
http.serveand the web libraries, which let your script handle HTTP requests. The execution server is the host that runs scripts on demand.
Starting it
The server binds loopback (127.0.0.1) by default, so it’s private to the
machine. Exposing it publicly (--bind 0.0.0.0) requires an auth token.
$ langoost server # local only
$ langoost server --bind 0.0.0.0 --auth-token "$TOKEN" # public, authenticated
| Flag | Default | Description |
|---|---|---|
--bind | 127.0.0.1 | Interface to bind; 0.0.0.0 exposes it publicly |
--port | 8080 | Port to listen on |
--auth-token | $LANGOOST_AUTH_TOKEN | Bearer token required for /execute and /cache |
--dir | . | Directory searched for .goost files |
--max-source-bytes | 1 MiB | Cap on submitted source/file size |
--allow-stdlib | all | Comma-separated stdlib allowlist (empty = allow all) |
--pprof :ADDR | off | Expose Go’s net/http/pprof |
Authentication
When an --auth-token is set, POST /execute and DELETE /cache require a
matching Authorization: Bearer <token> header (GET /health stays open). A
public bind without a token is refused unless you pass the explicit
--unsafe-allow-no-auth escape hatch — never do that in production.
curl -s localhost:8080/execute \
-H "Authorization: Bearer $TOKEN" \
-d '{"source": "print(1 + 1)"}'
POST /execute
Run a script. The JSON body selects what to run:
| Field | Type | Description |
|---|---|---|
source | string | Inline Langoost source to compile and run |
file | string | Path to a .goost file to run (resolved under --dir) |
file_name | string | Name used for error messages / source mapping |
fn | string | Optional: a function to call after the script loads |
Provide either source or file. On success the response is 200 with the
captured stdout, the script’s (or function’s) return value, and the timing:
curl -s localhost:8080/execute -d '{
"source": "let x = 21\nprint(x * 2)"
}'
{
"output": "42\n",
"return": null,
"duration_ms": 1
}
Call a specific function in a file:
curl -s localhost:8080/execute -d '{
"file": "handlers.goost",
"fn": "handle"
}'
If the script throws or fails to compile, the response is 422 with the error, any output produced before the failure, and the duration:
{
"error": "handlers.goost:7: undefined variable \"x\"",
"output": "",
"duration_ms": 0
}
Malformed JSON returns 400; a non-POST method returns 405.
GET /health
Liveness and status, including how many modules are currently cached:
curl -s localhost:8080/health
{
"status": "ok",
"version": "0.1.0",
"cached_modules": 3
}
DELETE /cache
Clear the compiled-module cache. Modules are recompiled on the next import —
useful during development after editing a .goost module that the server has
already loaded:
curl -s -X DELETE localhost:8080/cache
{ "status": "cache cleared" }