Build

Deploy via Playground

Five minutes from “I have a Claude agent” to “it's running on Theseus.”

In one paragraph

Visit play.theseus.network, pick the BYO Markdown Agent template, edit the frontmatter + system prompt, click Deploy. The playground synthesises agent.rs from your markdown, compiles in the browser via WASM, and submits the SCALE bytes to the chain. No Rust to write. The other 16 templates work the same way; this guide picks the simplest path.

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 CLI, see /docs/quickstart instead.

Pick the right starter template

The “+ New workspace” picker has 17 templates. Three matter when porting an existing tool-using agent:

TemplateWhen to pick it
BYO Markdown AgentYou have a Claude/OpenAI tool-loop agent and want to ship without touching Rust. Tools declared in YAML frontmatter;agent.rs is synthesised at compile. Default recommendation.
BYO Typed AgentYou want explicit control over the SHIP IR — custom node graphs, HITL pauses, parallel sub-agent calls. Each tool is a hand-written ToolSpec in agent.rs.
BYO AgentLightest path: every tool call goes through one generic fetch_url(url, body) surface. Lowest registration cost, lowest tool-selection quality. Good for prototyping.

The 13 demo templates (vellum, aave-spot, aviation, governance, etc.) are full working agents — read their code to see what's possible, or fork one for ideas.

The 5-step deploy

1Open the playground

Visit play.theseus.network. Click your workspace name (top left) → + New workspace → pick BYO Markdown Agent — frontmatter only, no Rust from the dropdown → name it → Create.

You'll see two files in the file tree:

text
THESEUS.md
skills/
  my-tools/
    SKILL.md

That's the whole agent. No agent.rs.

2Edit THESEUS.md

The template ships as a working “Weather Assistant” you can deploy as-is. To make it yours:

yaml
---
name: My Agent                 # display name on chain
id: my-agent-v1                # stable on-chain handle (don't change after deploy)
model: deepseek-chat           # which registered model to use
native-tools: none             # opt out of the built-in tokens.*, chain.*, bridge.* surface
tools:
  - name: get_weather          # MUST match a proxy_tools entry on the tool-executor
    description: Get the current temperature (Celsius) for a city.
    args:
      city: string
    return: string
  - name: lookup_user
    description: Read a user record by id.
    args:
      user_id: string
    return: string
---

You are a helpful assistant.

When the user asks about weather, call `get_weather` with the city.
When the user asks about a user account, call `lookup_user` with the
user id. Otherwise just answer directly.

The body below the frontmatter is the system prompt — same shape and conventions as a Claude or OpenAI system prompt. Be specific about when to call each tool.

Supported arg types: string | number | bigint | boolean.

3Edit skills/my-tools/SKILL.md

The skill is how the model discovers which tools to consider for a task. List each tool's purpose:

markdown
---
name: my-tools
description: Catalog of weather + user-lookup tools.
allowed-tools: get_weather lookup_user
---

# Tools

## `get_weather`

Use when the user asks about weather. One argument: `city`. Returns
JSON with `temperature` and `conditions`.

## `lookup_user`

Use when the user asks about a user account. One argument: `user_id`.
Returns `name`, `email`, `preferences`.

The allowed-tools: line must list every tool you want the model to have access to via this skill (space-separated).

4Set up your tools as HTTP endpoints

Your existing tool code keeps running wherever it lives today — you just need to expose each one as a POST endpoint:

http
POST https://your-server/get_weather
Content-Type: application/json

{"city": "Tokyo"}

…returning the tool's result as the response body. FastAPI, Express, Cloudflare Workers, ngrok during dev — all fine.

Then the operator running the tool-executor needs a proxy_tools: entry per tool in their config:

yaml
proxy_tools:
  - name: get_weather
    endpoint: https://your-server/get_weather
  - name: lookup_user
    endpoint: https://your-server/lookup_user

Names must match exactly

The three names — tools: in your frontmatter, allowed-tools: in your skill, and proxy_tools: on the tool-executor — must match exactly. A typo on any side surfaces as Unknown tool: <name> at runtime.

5Deploy

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

  1. Reads your THESEUS.md frontmatter
  2. Synthesises an agent.rs from the tools: list (you don't see this)
  3. Compiles the whole thing via WASM into SCALE bytes
  4. Signs with your connected wallet (today: //Alice in dev; wallet integration coming) and submits the register_agent extrinsic

You'll see “Agent registered” with your agent's SS58 and a link to the chain explorer. The agent is live; you can prompt it from the panel right underneath.

What you get on chain

  • A deterministic content hash for the deployed agent (hash of the SCALE bytes). Anyone can re-derive it from your published THESEUS.md + skills.
  • An on-chain account for the agent (the SS58 above). It has its own keypair, can hold THE, can spend on its own operations.
  • Every model invocation queued as a chain event; every tool dispatch recorded with content_sha256 of the response.
  • Skills with their allowed-tools field declared — forward-compatible with the active-allowed-tools filter when it ships.

When to drop into Rust

The synthesised agent.rs covers ~95% of agents (a tool-loop with init → think → act → loop → done). You add your own agent.rs to the workspace 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
  • Native tool calls mixed with external HTTP

Add an agent.rs to the workspace; the playground uses yours instead of synthesising one. Start with BYO Typed Agent for a worked example.

When something breaks

You seeWhat it meansFix
Unknown tool: <name> at runtimeThe model called a tool the tool-executor doesn't haveAdd the proxy_tools: entry with the matching name
Agent stalls without committingModel narrating instead of calling toolsTighten the system prompt — “Do not narrate. Call the tool ONCE.”
405 Method Not Allowed on a toolYour endpoint doesn't accept POSTMake sure your handler is POST, not GET
Compile error on the WASM sideagent.rs (yours or synthesised) doesn't satisfy the walkerDrop the custom agent.rs to let the synth run; report the synth bug if it persists
model not registeredThe model: in your frontmatter isn't on chainPick one of the registered tags (deepseek-chat, gpt-5.1, claude-sonnet-4-5)
Documentation