Welcome to Agents Academy
Module 09 · Building · ~10 min
agents-starter.
By the end of this module, you’ll have a real, runnable trading agent on your laptop, not a tutorial snippet, but the same starter every Limitless agent in production was forked from.
To get there, you’ll work with the bootstrap repo for Limitless agents. Clone it, dry-run certainty-closer (the SDK-only strategy SKILL.md recommends as your first run, no extra feeds or setup), graduate to the flagship cross-market-mm, and read SKILL.md as a coding-agent operating manual. Module 10 then teaches the parallel paradigm, custom write-side skills your runtime LLM agent calls as tools.
Building tier · Reference cardWhat is the agents-starter repo for Limitless trading agents?
agents-starter (github.com/limitless-labs-group/agents-starter) is the Node.js/TypeScript bootstrap repo Limitless production agents are forked from: three runnable strategies (cross-market-mm, oracle-arb, certainty-closer), a redeem utility, and SKILL.md, an operating manual a coding agent like Claude Code or OpenClaw can follow end to end. The paradigm differs from a runtime tool-use loop: strategies are plain TypeScript built on the official @limitless-exchange/sdk, and the LLM sits outside the repo as a coding agent that reads SKILL.md (~3,300 lines, the source of truth over the README) and drives the npm scripts. Credentials live in .env: PRIVATE_KEY for a dedicated trading wallet plus the primary scoped HMAC token (LMTS_TOKEN_ID, LMTS_TOKEN_SECRET), with DRY_RUN=true as the default so decisions print without orders hitting the chain. SKILL.md recommends certainty-closer, the SDK-only strategy with no external feeds, as the first dry run; the exact install, init, funding, and deploy steps are canonical in the repo’s AGENTS.md, QUICKSTART, and SKILL.md, not in any lesson.
Verified against source, 2026-06-09.
The repo is the source of truth for setup and run commands.
This module teaches the why; the exact, current how (install, the guided init, funding via the deposit-wallet bridge and the deposit command, deploy, the operator-panel data contract) lives in the repo and changes with the code. Read it there, do not rely on commands copied into a lesson: AGENTS.md (the operating contract), QUICKSTART, and SKILL.md.
Section 01
Repo tour.
github.com/limitless-labs-group/agents-starter is a Node.js/TypeScript bootstrap repo built as an OpenClaw skill. It ships three concrete strategies (cross-market-mm [the flagship cross-venue market maker], oracle-arb, certainty-closer) plus a redeem utility and per-strategy analyze. Install via the one-line installer (curl -fsSL … | sh) or git clone + npm install + npm run cross-market-mm:init. Your first dry-run is certainty-closer, the SDK-only starting point SKILL.md recommends.
Paradigm shift from Modules 04–06
Modules 04–06 covered runtime tool-use agents: an LLM loop that calls browse_markets, place_limit_order, etc. as tools. The agents-starter repo uses a different paradigm: you write trading strategies in plain TypeScript, and a coding agent (Claude Code, OpenClaw, or any agent with file + shell access) reads SKILL.md and runs the strategies via npm run …. Both paradigms are valid; this module teaches the second one. You can mix, the trading strategies here can be called as tools from a Module 04–06-style runtime agent too.
Top-level layout:
src/core/
Built on official SDKs (not a hand-rolled client): limitless/sdk-trading.ts (SDKTradingClient wrapping @limitless-exchange/sdk), limitless/markets.ts, limitless/redeem.ts, limitless/portfolio.ts, limitless/websocket.ts, limitless/approve.ts, limitless/derive-token.ts, limitless/types.ts (trading.ts/sign.ts are LEGACY); polymarket/{client,ws}; price-feeds/hermes.ts; telegram/client.ts; kelly.ts; and a wallet.ts wrapper around viem.
src/strategies/
A base-strategy.ts abstract class plus three concrete strategies in their own folders: cross-market-mm/ (the flagship, with its own runtime loop and subcommands, not BaseStrategy), oracle-arb/, and certainty-closer/ (both extend BaseStrategy). Each contains an index.ts (the strategy class) and a run.ts (the CLI runner). There is also a tests/ suite (vitest) and .github/workflows/ci.yml. The canonical pattern for adding your own strategy is shown in Section 04.
SKILL.md
The operating manual for a coding agent. When Claude Code or OpenClaw opens the repo, it reads SKILL.md to learn the setup wizard, the scoped HMAC token auth (LMTS_TOKEN_ID + LMTS_TOKEN_SECRET are the PRIMARY credentials; the SDK auto-signs requests), the safety env vars, and the iteration loop. It’s ~3,300 lines, treat it as the source of truth for the repo, not the README. Each strategy folder also has its own SKILL.md/QUICKSTART.md.
.env.example
Template covering PRIVATE_KEY plus the primary scoped HMAC token (LMTS_TOKEN_ID, LMTS_TOKEN_SECRET; legacy LIMITLESS_API_KEY is only a fallback), the DRY_RUN=true default, and per-strategy sizing (ORACLE_BET_SIZE; CC_BANKROLL/CC_MAX_RISK/CC_KELLY_FRACTION; cross-market-mm uses order_size + a max_loss_usd circuit-breaker in its YAML config). Defaults to dry-run.
docs.limitless.exchange/mcp
A live MCP endpoint over JSON-RPC + SSE that exposes two tools: search_limitless_exchange (semantic search across docs) and query_docs_filesystem_limitless_exchange (read-only shell into a virtualised docs filesystem, rg, cat, tree, etc). SKILL.md instructs coding agents to query the MCP before writing any new API call, treat it as the source of truth for endpoint shapes and error codes.
Section 02
The starter strategies.
The repo ships with three ready-to-run strategies plus a redeem utility and per-strategy analyze. Each strategy lives under src/strategies/<name>/ as index.ts plus run.ts (the runner). oracle-arb and certainty-closer extend BaseStrategy, whose base class drives the loop, initialize() → tick() → execute decisions → wait → repeat, while the flagship cross-market-mm runs its own runtime loop. Module 10 walks the parallel paradigm (skills for runtime LLM agents); the canonical pattern for writing your own BaseStrategy is shown in Section 04 below.
certainty-closer
SKILL.md first runCertainty closer (recommended first run, SDK-only)
Buys near-resolution favourites, sized with fractional Kelly (core/kelly.ts). No external feeds, the simplest template, which is why SKILL.md uses it for the first dry run.
npm run certainty-closer
oracle-arb
Oracle arbitrage
Connects to Pyth Hermes SSE for sub-second oracle prices and fires FOK orders against the actual orderbook ask when the market hasn’t priced in the move. Includes orderbook validation, position tracking, and auto-approval. The most complete reference example.
npm run oracle-arb
cross-market-mm
FlagshipCross-market market maker
Quotes on Limitless and hedges fills on Polymarket for a delta-neutral book; earns cross-venue spread + Limitless maker rebates + LP rewards. Runs its own runtime loop with subcommands (init/find-pairs/setup-poly/preflight/flatten/close/status/analyze) and a YAML config.
npm run cross-market-mm
ops utilities
Redeem, analyze, observability
A redeem CLI with check <slug>, claim <slug>, claim-many, and claim-all subcommands; per-strategy analyze that reads your trade log for win rate by asset, edge distribution, and parameter suggestions; and observability via per-strategy :status JSON (e.g. data/cross-market-mm-status.json) plus optional Telegram alerts.
npm run redeem claim-all · npm run cross-market-mm:analyze · npm run cross-market-mm:status
Section 03
Running the starter.
Clone the repo, npm install, copy .env.example to .env, and run one of the strategies. It starts in dry-run mode by default (DRY_RUN=true), every decision is printed, but no orders hit the chain. Leave it in dry-run for at least one full day before flipping DRY_RUN=false. SKILL.md’s setup wizard recommends certainty-closer as the first strategy to dry-run because it is SDK-only and needs no external feeds or extra configuration. The repo is Node.js/TypeScript; there is no Python flavour.
How to run this
- Install Node 18+ (node --version) and make sure git and npm are on your PATH.
- After cp .env.example .env, fill in PRIVATE_KEY and the primary scoped HMAC token (LMTS_TOKEN_ID, LMTS_TOKEN_SECRET), keep DRY_RUN=true, and set per-strategy sizing. Bridge a few USDC on Base plus a small amount of ETH for gas to the wallet before flipping DRY_RUN=false.
- Run the shell block above line-by-line, clone, npm install, npm run cross-market-mm:init to bootstrap, then npm run certainty-closer from the agents-starter directory. Confirm zero orders are placed before moving to live trading.
- Save the Python snippet as drive_starter.py, point REPO at your local agents-starter clone, then run python drive_starter.py.
- Watch the per-strategy status file in another terminal via npm run cross-market-mm:status (or wire up optional Telegram alerts) to track live positions and PnL. Once positions resolve, run npm run redeem claim-all to convert winning tokens to USDC.
# Module 09: Clone and run the starter
# Real README: https://github.com/limitless-labs-group/agents-starter
# Source of truth: SKILL.md at the repo root
# One-line installer (clone + install in one step):
# curl -fsSL https://raw.githubusercontent.com/limitless-labs-group/agents-starter/main/install.sh | sh
# ...or do it by hand:
git clone https://github.com/limitless-labs-group/agents-starter.git
cd agents-starter
# 1. Install dependencies (Node 18+ required)
npm install
# 2. Set env vars (copy .env.example to .env, then edit)
cp .env.example .env
# REQUIRED:
# PRIVATE_KEY=0x... (dedicated trading wallet, NOT your main)
# LMTS_TOKEN_ID=... (primary scoped HMAC token; SDK auto-signs)
# LMTS_TOKEN_SECRET=... (legacy LIMITLESS_API_KEY is only a fallback)
# SAFETY (default):
# DRY_RUN=true
# PER-STRATEGY SIZING (tune before going live):
# ORACLE_BET_SIZE=... (oracle-arb)
# CC_BANKROLL=... CC_MAX_RISK=... CC_KELLY_FRACTION=... (certainty-closer)
# cross-market-mm: order_size + max_loss_usd circuit-breaker in its YAML config
# Fund the wallet with USDC + a few cents of ETH for gas on Base.
# 3. Bootstrap, then dry-run the recommended starter strategy
npm run cross-market-mm:init # guided bootstrap (config + checks)
npm run certainty-closer # SDK-only first dry-run (per SKILL.md)
# Expected output (illustrative):
# Certainty Closer
# Mode: DRY RUN (no trades)
# Buying near-resolution favourites, fractional Kelly sizing
# [info] Wallet initialized {"address":"0xabc..."}
# [info] Scanning 9 near-resolution markets (favourite ≥ 0.90)
# [info] DRY → would BUY YES @ 0.94, kelly-size $0.42, edge=0.04
# 4. Other strategies
npm run oracle-arb # Pyth Hermes SSE oracle arb (FOK orders)
npm run cross-market-mm # flagship cross-venue market maker (delta-neutral)
# 5. Ops utilities
npm run redeem claim-all # claim every resolved position via the SDK
# (npm 7+; on npm 6 use: npm run redeem -- claim-all)
npm run cross-market-mm:status # read data/cross-market-mm-status.json
npm run cross-market-mm:analyze # win rate by asset, edge distribution from your trade log
# 6. Install PM2 once for long-running supervision (used in step 8 for go-live)
npm i -g pm2
# 7. Pre-approve a market before going live (recommended for clean demos)
# Without this, the first BUY order fails with "Insufficient collateral allowance".
# The approval covers every market sharing the same exchange venue.
npx tsx src/index.ts approve <any-active-market-slug>
# 8. Go live when you're ready: set DRY_RUN=false in .env, restart.
# Module 09: agents-starter is a Node.js/TypeScript repo.
# There is no Python flavour. To run it, you need Node 18+ installed;
# you can still drive it from a Python process by spawning npm as a subprocess.
# From shell (same as the TS tab):
# git clone https://github.com/limitless-labs-group/agents-starter.git
# cd agents-starter
# npm install
# cp .env.example .env # PRIVATE_KEY, LMTS_TOKEN_ID, LMTS_TOKEN_SECRET,
# # DRY_RUN=true, per-strategy sizing
# npm run certainty-closer # SKILL.md's recommended first dry-run (SDK-only)
# From Python: spawn npm as a subprocess if you want to orchestrate
# it from a Python agent runtime (e.g. a cron/scheduler wrapper):
import os
import subprocess
from pathlib import Path
REPO = Path("/path/to/agents-starter")
def run_strategy(name: str, dry_run: bool = True) -> None:
"""name: certainty-closer | oracle-arb | cross-market-mm"""
env = {
**os.environ,
"DRY_RUN": "true" if dry_run else "false",
}
subprocess.run(
["npm", "run", name],
cwd = REPO,
env = env,
check = True,
)
if __name__ == "__main__":
run_strategy("certainty-closer", dry_run=True)
# run_strategy("oracle-arb")
# run_strategy("cross-market-mm") # flagship cross-venue market maker
# If you'd rather write strategies directly in Python, skip agents-starter
# and use the official limitless-sdk Python package (see Module 03 + SKILL.md §7).
# agents-starter is built on the official @limitless-exchange TypeScript SDK;
# the Python limitless-sdk is a separate, equivalent path if you'd rather
# write strategies in Python.
Section 04
SKILL.md & strategy customisation.
The starter doesn’t have a “system prompt” file because the runtime isn’t an LLM loop, the LLM sits outside the repo as a coding agent. Instead, SKILL.md at the repo root is the operating manual: it walks the agent through clone → install → configure → dry-run → approve → go live, with a Quick Start prompt at the top that hands the wizard off in one paste. To specialise behaviour, you either (a) tune the per-strategy env vars in .env, (b) edit a strategy class under src/strategies/<name>/index.ts, or (c) write your own strategy by extending BaseStrategy, the canonical pattern is shown below.
// Module 09: src/strategies/my-strategy/index.ts
// Extend BaseStrategy, implement initialize / tick / shutdown / getStats.
// The base class drives the loop: it calls tick() on a timer and executes
// each TradeDecision via SDKTradingClient. DRY_RUN is honoured automatically.
//
// Note: imports use the .js extension because the repo is ESM ("type":"module").
import {
BaseStrategy,
StrategyConfig,
TradeDecision,
StrategyStats,
} from '../base-strategy.js';
import { LimitlessClient } from '../../core/limitless/markets.js';
import { SDKTradingClient } from '../../core/limitless/sdk-trading.js';
export class MyStrategy extends BaseStrategy {
constructor(
config: StrategyConfig,
deps: { limitless: LimitlessClient; trading: SDKTradingClient },
) {
super(config, deps);
this.tickIntervalMs = 30_000; // how often tick() runs; default is 60_000
}
async initialize(): Promise<void> {
// One-time setup: warm caches, load state, check approvals.
this.logger.info('MyStrategy initialised');
}
async tick(): Promise<TradeDecision[]> {
// 1. Discover candidate markets (CLOB venue only).
const markets = await this.limitless.getActiveMarkets({ tradeType: 'clob' });
// 2. Decide. TradeDecision shape is the contract: see base-strategy.ts.
const decisions: TradeDecision[] = [];
for (const market of markets) {
const yesPrice = market.prices[0] / 100; // prices are 0–100
if (yesPrice < 0.45) {
decisions.push({
action: 'BUY',
marketSlug: market.slug,
side: 'YES',
amountUsd: 1.0,
priceLimit: Math.floor((yesPrice + 0.02) * 100), // cents
reason: `YES at ${yesPrice.toFixed(2)} below 0.45 floor`,
});
}
}
return decisions; // the base class submits these via this.trading.createOrder()
}
async shutdown(): Promise<void> {
this.logger.info('MyStrategy shutting down');
}
getStats(): StrategyStats {
return { activePositions: 0, totalVolumeUsd: 0, pnlUsd: 0, lastTickDurationMs: 0 };
}
}
// Add a runner at src/strategies/my-strategy/run.ts that wires LimitlessClient
// and SDKTradingClient together (mirror src/strategies/oracle-arb/run.ts).
// Then a package.json script:
// "my-strategy": "npx tsx src/strategies/my-strategy/run.ts"
//
// Then: npm run my-strategy
# Module 09: SKILL.md (what Claude Code / OpenClaw reads on open)
#
# SKILL.md is Markdown at the repo root, not a Python file. It's shown
# here in the Python tab as reference text because the starter repo
# itself is TypeScript only. Paraphrased outline of the real ~3,300-line
# file:
# ---------------------------------------------------------------
# # Limitless Prediction Market Trading Agent
# Complete SDK and strategy framework. This file is the operating
# manual: an agent with shell access can go zero-to-live by following it.
#
# ## Quick Start Prompt
# A copy-pasteable prompt that hands the wizard off to a coding agent.
# (or just: install.sh, then npm run cross-market-mm:init)
#
# ## Agent Setup Wizard (7 steps)
# 1. Clone & install
# 2. Configure credentials (PRIVATE_KEY + LMTS_TOKEN_ID/LMTS_TOKEN_SECRET in .env)
# 3. Verify wallet (one-shot viem snippet to read USDC balance on Base)
# 4. Dry run → npm run certainty-closer
# 4b. Token approvals (CRITICAL before going live)
# npx tsx src/index.ts approve
# 5. Go live → set DRY_RUN=false, run under PM2
# 6. Monitor → per-strategy :status JSON (data/-status.json),
# optional Telegram alerts; redeem claim-all
# 7. Iterate → npm run :analyze, tune .env/YAML, restart
# Emergency stop → pm2 stop ; redeem claim-all
#
# ## Available Strategies (npm run )
# cross-market-mm cross-venue market maker, delta-neutral (flagship)
# oracle-arb Pyth Hermes SSE arb (FOK orders)
# certainty-closer near-resolution favourites, fractional Kelly (SDK-only)
#
# ## Live Documentation (MCP): the source of truth
# POST https://docs.limitless.exchange/mcp (JSON-RPC + SSE)
# Tools:
# - search_limitless_exchange(query) # semantic search
# - query_docs_filesystem_limitless_exchange(cmd) # rg/cat/tree on docs
# Use this BEFORE writing any new API call. Cached docs in this file
# may lag; the MCP endpoint always reflects the current state.
#
# ## Building Your Own Strategy
# Extend BaseStrategy in src/strategies//index.ts.
# Implement initialize(), tick(), shutdown(), getStats().
# Create src/strategies//run.ts (mirror oracle-arb/run.ts) and
# add a package.json script.
#
# ## Safety & Risk Management
# Per-strategy sizing (ORACLE_BET_SIZE; CC_BANKROLL/CC_MAX_RISK/
# CC_KELLY_FRACTION; cross-market-mm order_size + max_loss_usd circuit
# breaker in YAML). PM2 supervises long-running strategies; auto-restart
# with backoff.
# ---------------------------------------------------------------
# The coding agent uses SKILL.md like a runbook. When you tell it "dry-run
# certainty-closer for an hour and report PnL", it opens the file, finds
# the right npm command, runs it, and tails the status file.
The agents-starter repo: what people ask
Each answer also ships invisibly as schema.org FAQ data for search engines and AI assistants. Tap a question to expand.
-
What strategies ship with agents-starter?
Three, each undersrc/strategies/<name>/:certainty-closerbuys near-resolution favourites sized with fractional Kelly, no external feeds;oracle-arbconnects to Pyth Hermes SSE for sub-second oracle prices and fires FOK orders against the actual orderbook ask; andcross-market-mm, the flagship, quotes on Limitless and hedges fills on Polymarket for a delta-neutral book. A redeem CLI (check,claim,claim-many,claim-all) and per-strategyanalyzeround out the ops surface. -
Which agents-starter strategy should you dry-run first?
certainty-closer: it is the SDK-only starting pointSKILL.mdrecommends because it needs no external feeds or extra configuration. The repo defaults toDRY_RUN=true, so every trade decision is printed but no orders hit the chain. Leave it in dry-run for at least one full day, and confirm zero orders were placed, before flippingDRY_RUN=false. -
What is SKILL.md and why does it matter?
SKILL.mdat the repo root is the operating manual a coding agent reads when it opens agents-starter: a setup wizard from clone to go-live, the scoped HMAC token auth, the safety env vars, and the iteration loop. At ~3,300 lines, treat it as the source of truth for the repo, not the README. It also points agents at the live docs MCP endpoint,docs.limitless.exchange/mcp, to query before writing any new API call. -
What credentials and funding does agents-starter need?
PRIVATE_KEYfor a dedicated trading wallet (never your main) plus the primary scoped HMAC token,LMTS_TOKEN_IDandLMTS_TOKEN_SECRET; the SDK auto-signs requests, and the legacyLIMITLESS_API_KEYis only a fallback. Before going live, bridge a few USDC on Base plus a small amount of ETH for gas. Secrets stay in environment variables: a tool schema that accepts an API key as an argument makes the model the source of secrets, and the leak is silent. -
How is the coding-agent paradigm different from runtime tool use?
Runtime tool-use agents are an LLM loop calling functions likebrowse_marketsas tools. agents-starter inverts that: strategies are plain TypeScript (your own extendsBaseStrategyand implementsinitialize,tick,shutdown,getStats), and a coding agent with file and shell access readsSKILL.mdand runs them. Both paradigms are valid and they compose: the starter strategies can be called as tools from a runtime agent too.
Module checklist
Five quick confirmations.
Tick each item once you’ve actually done it. The Continue button unlocks at 5/5.
I cloned agents-starter, ran npm install, and copied .env.example → .env with my keys
I ran npm run certainty-closer in dry-run mode and saw trade decisions printed (no real orders placed)
I can point to each of the three bundled strategies in src/strategies/ (cross-market-mm, oracle-arb, certainty-closer) and run any of them with npm run <name>
I read SKILL.md and understand how a coding agent (Claude Code / OpenClaw) would orchestrate the strategies from it
I understand the paradigm shift: Modules 04–06 taught runtime tool-use agents, Module 09 teaches coding-agent-orchestrated trading strategies (both are valid, they compose)
Module 09 complete
Bootstrap ready.
Your agent has gone from notebook to repo. It’s a proper project now, with the structure, dry-run discipline, and operating manual that turn an experiment into something you’d actually deploy.
Concretely, you have a working starter agent running in dry-run mode. A real repo, three reference strategies (cross-market-mm, oracle-arb, certainty-closer) and a coding-agent operating manual, the scaffold every Production-tier module builds on.
A cloned agents-starter repo with .env configured for PRIVATE_KEY, the scoped HMAC token (LMTS_TOKEN_ID/LMTS_TOKEN_SECRET), DRY_RUN=true, and per-strategy sizing, the same layout every Production-tier module assumes.
Three runnable reference strategies (cross-market-mm, oracle-arb, certainty-closer), per-strategy status files + analyze, and a redeem CLI with claim-all, all behind npm run <name>.
A working mental model of the coding-agent paradigm: SKILL.md as runbook, the docs.limitless.exchange/mcp live-docs endpoint as the source of truth, BaseStrategy.tick() as the extension point, and the composability story that lets Module 04–06 tool-use agents orchestrate these same strategies.
Next up: the parallel paradigm, writing custom write-side skills a runtime LLM agent calls as tools, so it can compose CLI reads with native SDK orders.
Complete the checklist above to unlock