Skip to content

Run Polo locally

The local launcher, scripts/local_product.py, runs every Polo process on one computer: the API, the outbox relay, the scheduler, the Python worker and the services they depend on. Use it to try Polo, to develop against it and to verify changes. It is not a deployment tool; for a server, use Docker Compose or the Helm chart.

  • Node 24 or newer
  • Python 3.12 with uv
  • Docker
  • The Temporal CLI
  • A MinIO server binary
  • An OpenAI-compatible model endpoint, or a Claude or ChatGPT subscription (see below)

Any OpenAI-compatible endpoint on loopback works. For a free local model, run llama-server:

Terminal window
llama-server -m /path/to/Qwen3.5-9B-Q5_K_M.gguf --alias polo-local-qwen35 \
--host 127.0.0.1 --port 8097 -c 32768 -ngl 99 -fa on --jinja --no-ui --reasoning off
  1. Install the Python dependencies from the repository root:

    Terminal window
    uv sync --locked
  2. Initialise once. This writes the private configuration and generates every local secret:

    Terminal window
    python3 scripts/local_product.py init --minio /path/to/minio \
    --local-model-url http://127.0.0.1:8097/v1 --local-model-id polo-local-qwen35

    --local-model-url and --local-model-id go together, and the URL must be a loopback address. Leave both out if you will only use a subscription. init refuses to overwrite an existing configuration.

  3. Serve:

    Terminal window
    python3 scripts/local_product.py serve --allow-local-probes
  4. Open http://127.0.0.1:8088 (or http://localhost:8088; both loopback names are accepted) and choose Create a workspace.

serve builds the API and starts:

  • PostgreSQL and Redis in a private Compose project (compose.product.local.yaml)
  • a Temporal dev server
  • MinIO
  • the API on http://127.0.0.1:8088
  • the relay, the scheduler and the Python worker

It stops with an error if Node, npm, Docker, the Temporal CLI or the configured MinIO binary is missing, or if one of its ports is already in use.

Option Purpose
--directory The private state directory. Default ~/.local/share/polo/product-local.
--minio Path of the MinIO server binary. Defaults to minio on your PATH.
--local-model-url, --local-model-id The loopback model endpoint and the model name it serves (init).
--embedding-model Path of a local embedding model file; serve then also needs llama-server.
--allow-local-probes Lets uptime monitors probe loopback endpoints and lets MCP fixture servers on loopback be registered (serve).

A loopback model route gets a placeholder credential, and three times the hosted activity time limits and run claim, because local models answer slowly.

Everything the launcher keeps is under ~/.local/share/polo/product-local/ (or the directory you passed with --directory). The directory must have mode 0700 and must not be a symbolic link.

Path Content
config.json Ports, generated passwords, worker tokens and encryption keys
models.json The model registry the worker reads
logs/ One log per process
workspaces/ Task workspaces of the engineering sandbox
snapshots/ Workspace snapshots
objects/ MinIO object storage (artifacts)
temporal/ The Temporal dev server’s state
codex-home/ Polo’s own Codex sign-in, when you add a ChatGPT subscription

The default ports are 8088 (API), 55438 (PostgreSQL), 6398 (Redis), 7238 (Temporal), 8238 (Temporal UI), 9008 and 9009 (MinIO and its console).

The API serves the ui/ folder from an in-memory snapshot, so a change to the UI needs an API restart: stop serve and start it again.

Use your own Claude or ChatGPT subscription

Section titled “Use your own Claude or ChatGPT subscription”

Instead of an API key or a local model, Polo can think with your own Claude plan (through Claude Code) or ChatGPT plan (through Codex).

  1. Start serve and create your workspace.

  2. Name the workspace by the address in its sign-in link:

    Terminal window
    python3 scripts/local_product.py subscription --provider claude --workspace <workspace address>
    python3 scripts/local_product.py subscription --provider codex --workspace <workspace address>
  3. Restart serve.

  4. Open Settings → AI models. The model shows as “Claude subscription” or “ChatGPT subscription (Codex)”. Choose it for an agent on the Agents page.

What each provider uses:

  • Claude uses the Claude Code sign-in already on this computer. Sign in first with claude auth login and your Claude plan. The model defaults to sonnet; pass --model opus or a model ID to change it.
  • Codex gets its own sign-in for Polo, in codex-home inside the state directory. The first run opens a ChatGPT sign-in there. Polo never copies your own ~/.codex sign-in, because two copies of one sign-in invalidate each other when Codex refreshes it. The model defaults to the one your Codex uses.

Other options of the subscription action: --cli names the claude or codex executable when it is not found on its own, --effort low|medium|high sets the model’s reasoning effort, and --remove takes a workspace off, or removes the route when no workspace is named.

Each call runs the CLI in an empty directory with no tools, none of your own CLI settings, hooks, plugins or MCP servers, and none of Polo’s credentials. It returns only a typed answer. Calls are counted in tokens, not dollars, and your plan’s own limits apply: when the plan’s limit is reached, the task stops and says when it resets.

  • Quickstart: give Polo its first task.
  • Runners: start a customer runner next to the launcher so agents can propose real changes.
  • Testing: run the test suites against disposable services.