Build
Live · public testnet

Deploy via Playground

Five minutes from “I have an idea” to “a signed agent running on Theseus.”

In one paragraph

Sign in (email magic link, GitHub, or Google) and you get a workspace pre-seeded with the Hello Agent template and a custodial wallet on the hosted testnet (faucet button in the right-rail Network panel when balance dips). Edit THESEUS.md if you want, or just click Deploy this workspace. The browser compiles your agent via WASM, signs the register_ship_agent extrinsic from your wallet, and submits to chain. The agent is live; prompt it from the panel underneath.

This is the hands-on counterpart to /docs/agents (which covers the conceptual model: lifecycle, registration, fees, inter-agent interaction). If you'd rather build the chain from source and deploy via the local CLI, see /docs/quickstart instead.

The playground is open to everyone. Open the playground and run the same walkthrough below.

The 5-step deploy

1Sign in

Open the playground URL we sent you, then pick any sign-in method:

  • Email magic link (fastest, no account setup)
  • GitHub OAuth
  • Google OAuth

What sign-in gives you

  • A custodial wallet on the Theseus alpha chain. Keys generated server-side, scoped to your account.
  • Faucet access for deploy and inference fees. A Request THE button appears in the right-rail Network panel when your balance dips below the threshold.
  • Persistent workspaces tied to your account, synced across sessions in the same browser.

No real assets at risk; this is the hosted testnet. Bring- your-own key support lands in a near release.

2Create a workspace

Click the workspace name (top left) → + New workspace → type a name → press Enter. You'll get a fresh workspace pre-seeded with the Hello Agent template:

Playground file tree showing the Hello Agent workspace with agent.rs, THESEUS.md, tools.yaml, and skills/check-balance/SKILL.md.

Deploy as-is and you have a working greeter that can read its own on-chain balance. Or edit it to make it yours. Read on.

How the four files fit together

  • THESEUS.md holds the agent's on-chain identity (name, id, model) and the system prompt body. Same shape as a Claude or OpenAI system prompt.
  • tools.yaml declares the agent's tool surface in three optional blocks: native-tools: (runtime, on-chain), common-tools: (curated off-chain catalog), and byo-tools: (your own executor, inline JSON-schema). Absent native-tools: means “all natives available.”
  • skills/ are markdown files (one per skills/<name>/SKILL.md) that pair a procedure body with frontmatter: name, description, allowed-tools (a space-separated list), and an optional auto-activate boolean. When a skill activates, its body is injected into the system prompt and its allowed-tools enter the run's effective tool set. With auto-activate: true the skill is on from turn 1; with the default false, the model loads it by calling capabilities.describe.
  • agent.rs is the SHIP IR program the chain compiles. The default file ships a standard tool-loop (init → think → act → loop → done) that reads THESEUS.md, tools.yaml, and the skills directory at compile time. Edit it only if you need a non-standard graph (parallel sub-agents, HITL pauses, scheduled triggers).

Day-to-day, most authoring happens in THESEUS.md and the SKILL.md files. tools.yaml is one-time setup per tool surface. agent.rs stays as it ships unless you need custom control flow.

3Edit THESEUS.md

Frontmatter sets the agent's identity and which model it calls. The body is the system prompt, same shape as a Claude or OpenAI system prompt.

THESEUS.md open in the Playground editor with My Agent frontmatter and a short system prompt.

Frontmatter is only name / id / model. Tool permissions live in tools.yaml, not here.

The hosted alpha ships with claude-sonnet-5 registered by default. The on-chain model registry grows over time; check the model dropdown in the deploy panel for the current list.

4Edit tools.yaml

Three optional blocks. All are independent; mix freely. Here's a worked example with one entry in each:

tools.yaml open in the Playground editor showing native-tools, common-tools, and byo-tools blocks with one example each.

The blocks in detail:

native-tools: on-chain, runtime-dispatched

Built into the chain. The current catalog has around twenty tools across four families: tokens.* (list, balance, info, get_allowance, transfer, approve), chain.* (evm_address, balance, transfer), bridge.* (query, send_token, send_the, send_message, deploy_ica, get_ica), abi.* (encode, decode), and capabilities.* (list, describe, search). Always available without an executor. Run capabilities.list from any agent for the current authoritative set. The block is an allowlist. Three rules:

  • Block absent → every native tool is available
  • Block present, non-empty list → restrict to those names
  • Block present, empty list ([]) → no native tools at all

common-tools: curated off-chain catalog

Opt-in to chain-curated off-chain tools (the runtime runs the executor for you; schemas live in the on-chain registry). Available today: web_search, web_fetch. Names are bare suffixes; the compiler maps them to canonical offchain.<suffix> identifiers.

byo-tools: your own executor

When you need a tool the runtime doesn't provide, you declare its schema inline and run an off-chain executor that picks up pallet_tools::Queued events from chain and answers them via pallet_tools::submit_tool_result. The compiler folds these into CompiledAgent.tools automatically.

auto-activate: true puts the tool's schema in the model payload from the first turn. With false, the model has to call capabilities.describe to load it. Set true for tools you want the model to use without discovery.

Skip this step on day one

The Hello Agent ships with no active tool declarations. Default = all natives available, no common, no BYO. Enough for a first deploy. Add tools when the agent actually needs them.

5Deploy

Click Deploy this workspace in the bottom-right. The playground:

  1. Reads THESEUS.md, tools.yaml, agent.rs, and any skills
  2. Compiles the whole thing via WASM into a SCALE-encoded CompiledAgent blob (tools declared in tools.yaml are folded into the agent's tool set at compile time, overriding any tools: vec![...] the agent.rs holds)
  3. Signs the register_ship_agent extrinsic from your custodial wallet and submits it to chain
  4. Waits for finalisation, then surfaces the agent in the right rail

You'll see “Agent registered” with your agent's SS58 address and a link to the chain explorer. The agent address is deterministic in (deployer, compiled_hash, salt); changing any file rolls the address. Re-deploying the identical workspace fails on chain with AgentAlreadyExists. Use Deploy as fresh agent in the Network panel to rotate the workspace salt and get a new address.

After Deploy: prompting your agent

Once the register_ship_agent extrinsic finalises (a few seconds at 1-second block time), the agent shows up in the right-rail Your agents list. Click it to open a prompt panel underneath the editor. Type a message and send. What happens next:

  1. The playground signs a call_agent extrinsic from your wallet, attaching your prompt as input
  2. Chain emits a RunStarted event with your input bytes; the prover picks the run up and invokes the registered model
  3. If the model emits a tool call, the runtime dispatches it: native tools execute in-pallet; common tools route through the curated off-chain catalog; BYO tools emit a pallet_tools::Queued event for your executor to answer via pallet_tools::submit_tool_result. A tool call that isn't in the agent's active allowed-tools set fires ToolCallRejected instead of dispatching.
  4. The tool result (pallet_tools::Completed event) feeds back into the next model turn; the loop repeats until the model returns without a tool call
  5. The agent emits an End action; RunCompleted fires with the output bytes; the final reply appears in the prompt panel with a link to the chain explorer for the full event trace

Every event in the loop is signed and recorded on chain, so the whole run is replayable from the explorer afterwards.

What you get on chain

  • A deterministic agent address. address = blake2_256(b"theseus_agent_v1" | deployer | compiled_hash | salt) so the same workspace bytes from the same deployer always resolve to the same agent. The compiled_hash itself is a blake2 hash of the SCALE-encoded CompiledAgent; anyone can re-derive it from your published files.
  • An on-chain account for the agent (its own SS58). It has its own keypair, can hold THE, and can spend on its own operations. The Registered event records the agent's name, EVM address, version, endowment, compiled_hash, system_prompt_hash, and tools_count.
  • Every run is bracketed by RunStarted (with the input bytes) and RunCompleted (with the output bytes). Per-step events (StepEntered, StepDecisionMade, StepExited) and per-effect events (EffectQueued, EffectSettled) provide the full trace.
  • Every tool call writes pallet_tools::Queued (args inline) and Completed (result inline) or ToolCallRejected if the call wasn't in the active allowed-tools set. The active-tools filter is live, not pending.

Where your files live

Workspaces are stored in your browser's IndexedDB, tied to the account you signed in with. They persist across sessions and survive normal browser use. They do not survive:

  • “Clear all site data” or “Clear cookies and site data” for this domain
  • Manually wiping IndexedDB from devtools
  • Switching browsers or devices (no cross-device sync yet)

Keeping a backup

Until one-click GitHub sync and other save/upload paths ship, the safest route is to keep a canonical copy in git:

  1. Open each file in the playground
  2. Copy contents, paste into a local file in your repo
  3. Commit and push

This also gives you a version history of your agent.

On the roadmap

One-click GitHub sync (auth via your existing sign-in, writes file contents to a path in your repo) plus disk import/export. For long-running or production work today, the local CLI path is the right tool: see Quickstart Path B.

When to edit agent.rs

The default agent.rs is a standard tool-loop (init → think → act → loop → done) that handles request-response agents. Edit it when you need:

  • A different control-flow graph (parallel sub-agents, HITL pauses, scheduled triggers between loops)
  • Custom state fields beyond messages + model_out
  • Output schemas / structured ModelInvoke results
  • An input schema other than { prompt: string }

See /docs/ship for the full SHIP IR reference (node types, expression spec, state machine).

When something breaks

You seeWhat it meansFix
model not registered on deployThe model: in your frontmatter isn't on chainPick a tag from the deploy panel's model dropdown (e.g. claude-sonnet-5)
Agent stalls without committingModel narrating instead of calling toolsTighten the system prompt: “Do not narrate. Call the tool ONCE.”
Compile error on the WASM sideagent.rs doesn't satisfy the SHIP walkerRevert agent.rs to the template default and report the error if it persists
ToolCallRejected event after a tool callModel called a tool that isn't in the agent's active allowed-tools set (either no skill is on, or the active skill's allowlist doesn't include this tool)Add the tool to the active skill's allowed-tools frontmatter, or mark the skill auto-activate: true if it should be on from turn 1
BYO tool call hangs without completingNo executor is picking up the pallet_tools::Queued event for your byo-tools entriesPoint a tool-executor sidecar at the agent (see /docs/tools), or switch the tool to a common-tools: entry if a curated equivalent exists
insufficient balance on deployWallet too low for the deploy fee + endowmentClick Request THE in the right-rail Network panel to drip from the faucet

Ready to run the walkthrough?

The playground is live and open on the hosted testnet. Sign in, edit a markdown agent, and deploy. The walkthrough above is the exact flow.

Open the playground
Theseus Playground IDE preview.

Playground IDE preview

Documentation