Option 1: Use the Skill Builder (recommended)
Install the Skill Builder and describe your strategy in plain language:- External API signal (weather data, RSS feeds, price oracles) → deterministic trading
- Filter-and-trade (scan Simmer markets, filter by criteria, trade matches)
- Agent-as-oracle (your agent estimates probabilities using LLM reasoning, the script handles bias correction, Kelly sizing, and limit order execution)
Worked example: turn a World Cup strategy thread into a skill
If you came from the World Cup campaign page, paste the strategy in plain language. You do not need to know the SDK first. Example prompt:
Good generated output is narrow and testable:
This pattern also works for other World Cup ideas. The important move is to convert “market lag” or “momentum” into one measurable signal, one entry gate, one sizing rule, and one exit rule. Examples:
Keep the first skill small. A single World Cup signal with explicit caps is easier to test, publish, and remix than a broad “AI World Cup trader” with unclear authority.
Option 2: Build manually
A skill is a folder with three files:SKILL.md frontmatter
namemust be lowercase, hyphens only, match folder namedescriptionis required. AgentSkills spec allows up to 1024 chars, but keep it ≤160 chars — ClawHub truncates anything longer when generating the skill’s summary, and that truncated value is what appears as the one-line description onsimmer.markets/skills/<owner>/<slug>and in social-share cards. Write a complete sentence that fits.metadatavalues must be flat strings (AgentSkills spec)- No platform-specific config in SKILL.md — that goes in
clawhub.json
clawhub.json
automaton.managed: true means users can install the published skill and let the managed runner execute its cron for them. They do not need to keep a laptop or VPS online. Advanced users can still self-host a fork by running the script from cron on their own always-on machine; see Skills → Where does my agent run? for the managed vs self-hosted credential split.
Python script patterns
Hard rules
- Always use
SimmerClientfor trades — never call Polymarket CLOB directly - Always default to dry-run — pass
--liveexplicitly for real trades - Always tag trades with
sourceandskill_slug - Always include reasoning — it’s shown publicly
- Read API keys from env — never hardcode credentials
skill_slugmust match your ClawHub slug — this tracks per-skill volume- Frame as a remixable template — your SKILL.md should explain what the default signal is and how to remix it (see below)
- Pass
venue=explicitly when reading state —/trades,/portfolio, and/contextsupport avenuefilter. Rely on the default (all) only if you truly want cross-venue state. If your skill only trades on one venue, pass that venue on reads so you don’t confuse yourself with unrelated positions.
Remixable template pattern
Skills are templates, not black boxes. Your SKILL.md should include a callout like:Recommended: check context before trading
The/context endpoint provides trading discipline data — flip-flop detection, slippage estimates, and edge analysis. We strongly recommend checking it before executing trades:
Discovering markets already in Simmer
client.get_markets() is how you browse Simmer’s index. The trap: an unfiltered browse is server-windowed to at most 1,000 matching active markets, out of 20k+. A market can be absent from that window even though it’s fully tradeable — “not in get_markets()” does not mean “not imported.”
Always filter for discovery. SDK filters q=, tags=, venue=, and sort= are applied server-side before the cap, so they narrow the whole catalog first:
total is the size of that capped discovery window, not the full catalog count. If the server hit the ceiling, it returns truncated: true and capped_at_limit: true. To scan beyond 1,000, page across narrower slices: category tags, venues, keyword families, or time-to-resolution buckets. The REST endpoint also supports max_hours_to_resolution= for those time-window slices. Each slice gets its own top 1,000 after filters.
Before you conclude a market is missing and reach for import_market (below), confirm with a filtered q= search or client.check_market_exists(...). Re-importing a market that’s already indexed just burns your daily import quota.
Discover-then-trade for arbitrary markets
If your skill discovers markets off-Simmer (e.g. via the Polymarket Gamma API by event slug, or by walking external trader portfolios), you can’t trade them viaSimmerClient.trade() until they’re in Simmer’s index — every trade endpoint, including paper modes, fetches the price from /api/sdk/context/{market_id} and 404s for unindexed markets.
The canonical pattern is: check (free) → import on miss → trade. Cache the result so subsequent scans skip both calls.
check_market_existsis free and doesn’t consume the import quotaimport_marketis rate-limited (10/100/250 per day by tier; on 429 the response includes anx402_urlfor $0.005/import overflow via USDC on Base)- Most popular markets are already in Simmer’s index — the check often returns existing IDs at no cost
- Persisting the cache across scans means steady-state cost approaches zero
check_market_exists(url=...) for check_market_exists(ticker=...) and import_market for import_kalshi_market.
Reading state across venues
A Simmer agent can hold positions across three venues at once: sim (paper trading with$SIM), polymarket (real USDC on Polygon), and kalshi (real USDC on Solana). They’re independent — a single agent can hold a $SIM paper position AND a real Polymarket position on the same market simultaneously.
The read endpoints are venue-aware. Always pass venue= explicitly when you know which one your skill cares about:
venue="all", which returns merged state across every venue. That’s what you want for a dashboard-style heartbeat check-in. It’s also what a single-venue skill should avoid on reads — you don’t want your polymarket copytrading skill to see a leftover paper position from a week ago and think it’s real exposure.
/api/sdk/briefing is the canonical cross-venue snapshot. Every agent heartbeat loop should use it:
/api/sdk/trades returns merged trade history by default, with each row tagged:
/api/sdk/portfolio and /api/sdk/context/{market_id} have per-venue buckets alongside the legacy flat fields. Read from the buckets:
portfolio.sim_balance, context.position, etc.) remain populated for backwards compatibility, but new skills should prefer the bucketed fields.
Recommended: redeem winning positions
Callauto_redeem() once per cycle to collect payouts from resolved markets. This handles both wallet types — managed wallets redeem server-side, external wallets sign and broadcast locally.
Recommended primitives
The SDK ships helper modules that handle common skill-builder tasks. Prefer these over rolling your own — they encode patterns from top traders, are tested, and are maintained alongside the SDK. Full reference: Position Sizing.Position sizing — simmer_sdk.sizing
Don’t hard-code stake amounts and don’t write your own Kelly. Use size_position(). It returns 0.0 when the edge is below your min_ev threshold, so the skill can simply skip the trade.
SIZING_CONFIG_SCHEMA into your skill’s CONFIG_SCHEMA — users get SIMMER_POSITION_SIZING, SIMMER_KELLY_MULTIPLIER, and SIMMER_MIN_EV env vars for free.
Top holders — client.get_top_holders()
See who else holds positions in a market before you trade. Calls the public Polymarket data API (free, no auth).
address, display_name, amount, outcome, and profile_url per holder. Use market.polymarket_condition_id (0x hex) — not the Simmer UUID or CLOB token ID.
External market data
The SDK doesn’t bundle third-party API clients. If your skill needs Polymarket metadata beyond whatSimmerClient.get_markets() exposes — categories, descriptions, full event groupings, raw volume and liquidity — call Polymarket’s Gamma API directly from the skill. It’s free, no auth, well-documented. Keep the helper next to the skill so the SDK stays scoped to Simmer’s surface area plus universal primitives.
Publishing
Node.js >= 22.12 required for all
npx clawhub@latest commands. Run node --version to check. The ClawHub CLI uses native fetch APIs introduced in Node 22.12; older versions will fail with a runtime error on the publish or install step.npx clawhub@latest (CLI 0.15.0+). MIT-0 is a no-attribution variant of MIT — no copyright notice required in distributions. To publish under a different license, include a LICENSE file in your skill folder before publishing; ClawHub’s moderation scanner will use it instead of the MIT-0 default.
Within ~6 hours, the Simmer sync job will:
- Discover your skill via ClawHub search
- Verify it has
simmer-sdkas arequires.pipdependency (this is the trigger — skills without it are ignored) - Add it to the registry at simmer.markets/skills
After publishing, verify the install path
Trading skills that reference crypto keys and call external APIs will sometimes get flagged by ClawHub’s VirusTotal Code Insight scanner — it’s a heuristic LLM scan and may return false positives on legitimate trading code. Verify installs work:⚠️ Warning: “your-skill-slug” is flagged as suspicious by VirusTotal Code Insight. Error: Use —force to install suspicious skills in non-interactive modeTwo fixes:
- Manifest mismatch (most common): make sure every env var and every capability your SKILL.md teaches is declared in
clawhub.jsonrequires.env. Republish as a new patch version. OpenClaw re-scans and clears its verdict. - VT Code Insight false positive: if OpenClaw is clean but VirusTotal still flags behavioral patterns (crypto keys + external HTTP + credential handling), email
simmer@agentmail.toand we’ll request a manual override from ClawHub. Include your skill slug and the scan report link fromhttps://clawhub.ai/skills/<your-slug>.
Distribute beyond Simmer (skills.sh)
Publishing to ClawHub (above) is what lists your skill in the Simmer registry. Keep doing that. For extra reach across other coding agents (Claude Code, Codex, Cursor, OpenCode, and 60+ more), you can also make the skill installable via skills.sh, the open agent-skills ecosystem. There is no separate publish step. skills.sh resolves skills straight from a public git repo:- Push your skill folder to a public GitHub (or GitLab) repo, e.g.
your-org/your-skills/<skill-slug>/SKILL.md. - Anyone, on any supported agent, can install it:
SKILL.md frontmatter (name + description) that ClawHub reads is what skills.sh reads, so no extra config is needed.
A public repo makes your skill installable immediately, but the skills.sh search and leaderboard rank by install count, so a brand-new skill won’t surface in discovery until it accrues installs. Share the direct
npx skills add command to drive those first installs. To keep a skill installable but hidden from skills.sh discovery, set metadata.internal: true in the frontmatter.Scanner compliance — passing ClawHub moderation
ClawHub runs an LLM-based moderation scanner (engine v2.4.22+) on every published skill. Skills flaggedsuspicious are hidden from search and blocked from non-interactive installs. The scanner reads your SKILL.md content — not just clawhub.json — and weighs the first ~30 lines most heavily.
Trading skills trip the scanner more often than utilities because the scanner’s ASI (Agentic Security Initiative) taxonomy flags “high-impact authority without clear scoping, reversibility, or containment.” The fix is straightforward: tell the scanner your skill is bounded.
1. Include a DISCLAIMER.md
Every trading or payment skill needs aDISCLAIMER.md in the skill folder. Template:
2. Reference DISCLAIMER.md in the first 30 lines of SKILL.md
The scanner weighs your opening content most heavily. Put the bounding warning right after the opening paragraph — before setup instructions, mode tables, or configuration details.3. Include quantitative bounding in the opening
The scanner looks for evidence that your skill constrains its own authority. Mention at least two of these in the first 30 lines:- Per-trade cap — “max $10 per trade”
- Per-run cap — “5 trades per scan cycle”
- Paper-mode default — “dry-run is the default;
--liverequired for real trades” - Sizing constraint — “Kelly capped at 25%”, “3% of bankroll per position”
- Scope constraint — “only zero-fee markets”, “only markets resolving within 7 days”
4. Lead with method, not action
The scanner flags aggressive action verbs in the title and opening line. Compare:
The slug can keep the punchy name (
polymarket-mert-sniper) — installed users reference it. But the SKILL.md description and opening line should lead with the methodology, not the action.
Quick checklist
Before publishing, verify:-
DISCLAIMER.mdexists in the skill folder - SKILL.md references it in the first 30 lines
- SKILL.md includes “Framework, not a production trading system” or “This is a template” in the first 30 lines
- At least two quantitative bounds mentioned in the opening (caps, paper-default, sizing)
- Title and opening line describe the method, not an aggressive action
- Every env var mentioned in SKILL.md is declared in
clawhub.jsonenvVars(see credential declaration above)
Naming conventions
Discoverability — name and category tabs
Display name
The Simmer registry renders your skill’smetadata.displayName on its card and
detail page. Set a clean human name:
polymarket-soccer-shock-ladder) is only the install ID and URL. If you
omit displayName, the registry falls back to the slug title-cased (“Polymarket
Soccer Shock Ladder”), which usually mangles acronyms and product names.
Category tabs
The/skills page has category pills (Sports, Crypto, Politics, Weather, and more).
Most are assigned automatically from your strategy, so you don’t set a category.
The World Cup tab is a campaign overlay with its own rule. It surfaces any skill
that either:
- mentions world cup, fifa, or soccer in its name or description, or
- declares a
world-cuptag.
player-goal-value skill), add the tag in your
SKILL.md frontmatter:
clawhub.json:
Updating skills
install_count and version info automatically.
Your SKILL.md body renders publicly
The markdown BODY of your SKILL.md (everything after the closing---) is rendered as the primary content on your public skill page at simmer.markets/skills/<owner>/<slug>. Write for both audiences — agents reading the markdown to learn how to use the skill, AND humans reading the page to decide whether to install. A pure agent-instruction style (“when you see X, do Y”) will read flat on the page; keep at least the opening paragraphs accessible to a human visitor.
Crediting another author (credit)
If your skill implements a strategy from someone else — a KOL’s X thread, a published quant write-up — credit them. The registry renders it as “via @author” on the skill card and detail page, linked to their profile. Add acredit object under metadata.simmer:
nameis required (the displayed handle or name).urlis optional and must behttp(s).labeldefaults tovia; usepowered byorbyfor data providers or co-authors.
- Ownership — who published the skill on ClawHub (shown as the skill’s owner).
- Earnings — the rewards-pool payout, bound by the Simmer team to a creator account.
Linking your content (links)
Skills that have been discussed externally — a tweet, blog post, YouTube video — can link back from the skill detail page onsimmer.markets/skills/<owner>/<slug>. Add a links array under metadata.simmer in your SKILL.md frontmatter:
- URLs must start with
https://orhttp://— other schemes are silently dropped - Up to 10 URLs per skill; extras are truncated
- Re-publish to update (sync picks up the new frontmatter within ~1 hour)
- Removal is additive-only in v1: clearing
linksfrom your SKILL.md does not remove existing entries from the registry. To delete a link, emailsimmer@agentmail.towith your skill slug and the URL to remove.
MCP Server
For agents that use MCP, see Agent Support for thesimmer-mcp server setup.