Skip to main content
A Sandcastle is a TextQL-managed, per-session Python/bash sandbox. It comes with a working filesystem, a stateful Python kernel, governed outbound network, your org’s connectors, and — when context is enabled — a permissioned, RBAC-pruned mount of your org’s Ontology (our persisted-memory layer) at /sandbox/files/library. This guide shows how to wire your own agent loop into a Sandcastle. There are two ways to do it — pick the one that fits your architecture. The Sandcastle is the same either way; what changes is where the loop runs.
The Sandcastle is the execution environment — your agent never has to touch our infra directly. You either run your loop inside it and let the agent use the filesystem and tools natively, or run your loop in your own infra and execute commands inside the Sandcastle remotely over the Sandcastle API.

Prerequisites

All Sandcastle endpoints live under /v2/sandcastles and authenticate with Authorization: Bearer <TEXTQL_API_KEY>.

Choose your topology

Agent loop outside

Your loop runs in your infra. You boot a Sandcastle and execute commands inside it remotely. Best when you already own the orchestration, want your loop next to your other services, or need to fan one loop across many Sandcastles. Fully supported today.

Agent loop inside

Your loop runs inside the Sandcastle. Your orchestrating code just boots the Sandcastle, pushes the agent, and starts it. The agent then reads/writes the filesystem and calls tools natively — no round-trip per step. Possible today via exec; not yet a packaged template.

Option A — Agent loop outside the Sandcastle

This is the “virtual bash tool” model: the loop lives in your orchestrating code and treats the Sandcastle as a remote execution + filesystem backend. Every tool call your model makes becomes an API call against the Sandcastle.
1

Start (or restart) a Sandcastle

Pass back a sandbox_id to resume a specific Sandcastle; omit it for a fresh one. The Sandcastle is keyed to your member, and its /sandbox/files/library mount is pruned to what your OWNERS permissions allow.
2

Wire each tool the model can call to an endpoint

3

Run your loop

4

Read the Ontology mount

The library is mounted read-only-ish at /sandbox/files/library. Your loop can cat/grep it like any directory:
Use execute (stateful kernel) for an iterative data-analysis loop where the model builds up dataframes across turns, and exec (one-shot) for filesystem/shell steps that don’t need shared state.

Option B — Agent loop inside the Sandcastle

Here the loop runs in the Sandcastle. Your orchestrating code’s only job is to boot the Sandcastle, push your agent code, and start it. The agent then uses the local filesystem and /sandbox/files/library mount directly — no per-step round-trip — and makes model/tool calls out through the Sandcastle’s egress proxy.
1

Start a Sandcastle and push your agent

2

Run the loop inside

Inside agent.py, your tools are just local calls — open(), subprocess, glob, grep over /sandbox/files/library. The agent never leaves the box for a tool step; it only leaves the box to call the model.

Outbound network

Sandcastle egress flows through a forward proxy that records every outbound call (host, status, bytes, duration) to an egress ledger and enforces an allowlist — you can see this in the Network tab of any Sandcastle. For the agent-inside topology this matters:
  • The model endpoint your loop calls (e.g. api.anthropic.com) must be permitted by the egress policy, or the call shows up as denied in the ledger.
  • In-cluster TextQL services are blocked from the Sandcastle except the sandbox proxy/query ports, so the agent reaches connectors and the Ontology through the provided mounts and the /query endpoint, not by calling internal services directly.
The agent-inside topology is achievable today through exec, but it is not yet a packaged template (no first-class “agent image”, no managed secret injection beyond per-call env). If you want fully managed in-sandbox agents, prefer Option A for now and talk to us about the roadmap.

Persisting changes back to the Ontology (writeback)

Both topologies can read /sandbox/files/library, and both can write back to it. Edits an agent makes to that mount are diffed against a baseline snapshot (/sandbox/files/.internal/library.snapshot) and surfaced as a change for review/approval before they land in canonical git — the same pipeline whether the edit comes from the in-product chat tool or the Sandcastle API.
1

Stage edits in the mount

2

(Optional) preview what would be written back

3

Author a change

The change is submitted for admin review (open), unless an auto-approve rule matches (approved, already live). See Create Ontology Change.
Writeback is an explicit, reviewed action — not a background auto-sync. Permissions are enforced twice (the mount is pruned to your OWNERS access, and every changed path is re-validated at merge), so a change can never widen access. If the library has drifted you’ll get has_conflicts: true; resolve the .rej markers and re-submit with the same change_number.

How this maps to the Ontology backend

When context is enabled, /sandbox/files/library is materialized per session from your org’s canonical, git-versioned Ontology:
  • On FSx ONTAP deployments, the worker mounts a writable FlexClone of the latest approved snapshot, pruned in-place to your OWNERS permissions — copy-on-write, so startup is fast and isolated per session.
  • On the default filestore backend, permitted contents are copied into the session tree.
Either way the mount is RBAC-scoped at materialization time and .git / OWNERS metadata is stripped or locked, so a Sandcastle only ever sees the slice of org memory the caller is allowed to see.