@moonpay/cli 1.49.1 → 1.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7OJWAG57.js → chunk-AOKKDF4V.js} +1 -1
- package/dist/{chunk-D75SATYI.js → chunk-DMVZB2YH.js} +3 -3
- package/dist/{chunk-W5YCGWNV.js → chunk-GJLMK3FI.js} +2 -2
- package/dist/{chunk-BC4XTACV.js → chunk-OXRTYCBT.js} +1 -1
- package/dist/{client-3U3POBAC.js → client-EBMO22CL.js} +1 -1
- package/dist/index.js +2 -2
- package/dist/{ledger-P2SJ2YCC.js → ledger-S3A7KL23.js} +2 -2
- package/dist/{mcp-EVOIW4EJ.js → mcp-YYGFZ5UU.js} +1 -1
- package/dist/{store-QMBXLZXK.js → store-C3SIF4VO.js} +1 -1
- package/package.json +1 -1
- package/skills/moonpay-artifact-builder/SKILL.md +667 -0
- package/skills/moonpay-automation-builder/SKILL.md +148 -0
- package/skills/moonpay-card-onboarding/SKILL.md +150 -0
- package/skills/moonpay-skill-builder/SKILL.md +157 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: moonpay-automation-builder
|
|
3
|
+
description: Author new automations for the MoonPay Agents app. Use when the user wants to schedule a recurring task — a daily portfolio email, an hourly price check, a weekly rebalance, a cron-triggered prompt. Automations are JSON entries that fire a prompt or skill on a cron schedule via either the Claude Code or Codex backend. This skill defines the JSON schema, where to write it, and how to pick a sensible cron.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# MoonPay Automation Builder
|
|
7
|
+
|
|
8
|
+
An automation is a saved prompt that the MoonPay Agents app fires on a cron schedule. The first fire spawns a fresh agent session; every subsequent fire `--resume`s the same session so the agent keeps its memory across runs. This is how "every morning, summarize my portfolio" or "every Monday at 9am, run my DCA strategy" actually run.
|
|
9
|
+
|
|
10
|
+
This skill is how new automations get authored.
|
|
11
|
+
|
|
12
|
+
## When to use this skill
|
|
13
|
+
|
|
14
|
+
- The user wants something to run on a schedule, not just one-shot.
|
|
15
|
+
- The user already has a skill or a prompt that works once and wants to run it on repeat.
|
|
16
|
+
- The user describes the trigger with words like "every day", "every Monday", "hourly", "twice a week", "at 9am".
|
|
17
|
+
|
|
18
|
+
If the user wants a one-shot future action ("remind me at 3pm"), suggest the `schedule` skill instead — that's cloud-side and one-time.
|
|
19
|
+
|
|
20
|
+
## On-disk format
|
|
21
|
+
|
|
22
|
+
All automations live in a single file:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
~/.moonpay-agents/automations.json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
It's a JSON array of automation objects. Each object:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"id": "<uuid v4>",
|
|
33
|
+
"name": "Morning portfolio check",
|
|
34
|
+
"body": "Run mp portfolio retrieve --json, summarize the top movers since yesterday, and Slack me a 3-bullet update.",
|
|
35
|
+
"cron": "0 9 * * *",
|
|
36
|
+
"backend": "claude",
|
|
37
|
+
"enabled": true,
|
|
38
|
+
"sessionId": null,
|
|
39
|
+
"lastRun": null,
|
|
40
|
+
"lastStatus": null,
|
|
41
|
+
"lastOutput": null,
|
|
42
|
+
"createdAt": "2026-05-14T17:00:00Z"
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
| field | required | notes |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `id` | required | UUID v4. Generate one if creating new. |
|
|
49
|
+
| `name` | required | Short label shown in the Automations view. |
|
|
50
|
+
| `body` | required | The prompt the agent runs on each fire. Write it like a normal user message — the agent sees this verbatim. |
|
|
51
|
+
| `cron` | required | 5-field cron: `min hour dom month dow`. See "Picking a cron" below. |
|
|
52
|
+
| `backend` | required | `"claude"` or `"codex"`. Default to `"claude"` unless the user prefers Codex. |
|
|
53
|
+
| `enabled` | optional | Defaults to `true`. Set `false` to author the automation without firing it. |
|
|
54
|
+
| `sessionId` | optional | Leave `null` — the app fills this in after the first fire. |
|
|
55
|
+
| `lastRun`, `lastStatus`, `lastOutput` | optional | Leave `null` — written by the app after each fire. |
|
|
56
|
+
| `createdAt` | required | ISO-8601 timestamp. Use the current time. |
|
|
57
|
+
|
|
58
|
+
The app reloads `automations.json` on every save, so writing directly to disk works — no IPC needed.
|
|
59
|
+
|
|
60
|
+
## Picking a cron
|
|
61
|
+
|
|
62
|
+
The format is the standard 5-field Unix cron: `minute hour day-of-month month day-of-week`. **Day-of-week is 0–6 with 0 = Sunday.**
|
|
63
|
+
|
|
64
|
+
| Cadence | Cron | Notes |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| Every minute | `* * * * *` | Don't. Almost always a bug. |
|
|
67
|
+
| Every 5 minutes | `*/5 * * * *` | Polling. Fine for cheap checks. |
|
|
68
|
+
| Every hour on the hour | `0 * * * *` | |
|
|
69
|
+
| Daily at 9am | `0 9 * * *` | Local time of the device running the app. |
|
|
70
|
+
| Every weekday at 9am | `0 9 * * 1-5` | Mon–Fri. |
|
|
71
|
+
| Every Monday at 9am | `0 9 * * 1` | |
|
|
72
|
+
| First of the month at 9am | `0 9 1 * *` | |
|
|
73
|
+
|
|
74
|
+
The MoonPay Agents app uses a 6-field internal form (`sec min hour dom month dow`) — it prepends `0 ` automatically. Always write 5-field cron in the JSON.
|
|
75
|
+
|
|
76
|
+
### Cron gotchas
|
|
77
|
+
|
|
78
|
+
- **Day-of-month + day-of-week are OR'd**, not AND'd. `0 9 1 * 1` fires on the 1st of the month AND every Monday — usually not what people want.
|
|
79
|
+
- **App must be running.** The scheduler is in-process; if the app is closed, the automation doesn't fire. (No launchd integration today.)
|
|
80
|
+
- **Time zone** = local machine time. If the user moves time zones, the cron fires at the same local time, not the same UTC time.
|
|
81
|
+
|
|
82
|
+
## Writing the `body`
|
|
83
|
+
|
|
84
|
+
The body is the prompt the agent gets on every fire. Two things to get right:
|
|
85
|
+
|
|
86
|
+
### 1. Write it like a normal user message
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Pull my Polymarket positions with mp polymarket positions list --json. For each position
|
|
90
|
+
where the current price has moved >5% from entry, draft a Slack message to #me with the
|
|
91
|
+
position name, entry price, current price, and PnL.
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Not:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Execute polymarket position summary procedure
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The agent reads the body the same way it reads a chat message. Be specific about what data to pull, what to do with it, and where to deliver the result.
|
|
101
|
+
|
|
102
|
+
### 2. Don't recreate skills inline
|
|
103
|
+
|
|
104
|
+
If the workflow already exists as a skill (`mp skill list`), invoke the skill instead of describing its steps:
|
|
105
|
+
|
|
106
|
+
> "Use the moonpay-portfolio skill. Compute drift from my target allocation and Slack me a one-line summary if drift > 5%."
|
|
107
|
+
|
|
108
|
+
This keeps the automation small and lets skill improvements propagate automatically.
|
|
109
|
+
|
|
110
|
+
### 3. Pick the right backend
|
|
111
|
+
|
|
112
|
+
- **`"claude"`** for anything that needs nuanced judgment, web research, or long-form output. Default.
|
|
113
|
+
- **`"codex"`** if the workflow is heavily code-modifying (e.g. "regenerate this report HTML and write it to disk") and you want Codex's editing harness.
|
|
114
|
+
|
|
115
|
+
## Authoring flow (what the agent should do)
|
|
116
|
+
|
|
117
|
+
When the user invokes you:
|
|
118
|
+
|
|
119
|
+
1. **Ask three things**:
|
|
120
|
+
- What should this automation do? (the body)
|
|
121
|
+
- How often? (the cron — in plain English, you'll convert)
|
|
122
|
+
- Backend? (default to claude unless they specify)
|
|
123
|
+
2. **Convert the cadence to a 5-field cron** and read it back to the user in plain English ("Every weekday at 9am — `0 9 * * 1-5`") to confirm.
|
|
124
|
+
3. **Read `~/.moonpay-agents/automations.json`** (create the file as `[]` if missing).
|
|
125
|
+
4. **Append a new automation object** with a freshly generated UUID v4, the current ISO-8601 timestamp for `createdAt`, the user's body, the cron, the backend, `enabled: true`, and `null` for `sessionId`/`lastRun`/`lastStatus`/`lastOutput`.
|
|
126
|
+
5. **Write the updated array back** to `~/.moonpay-agents/automations.json`. Pretty-print (2-space indent) — the user may edit it by hand.
|
|
127
|
+
6. **Tell the user**: when the next fire is, the name + cron, and that they can disable/edit it from the Automations view.
|
|
128
|
+
|
|
129
|
+
## Important rules
|
|
130
|
+
|
|
131
|
+
- **Never write to `automations.json` without reading it first.** Read → modify → write. Don't blow away other automations.
|
|
132
|
+
- **Always use UUID v4 for `id`** — incrementing IDs collide on import/export.
|
|
133
|
+
- **Use `null`, not `""` or `undefined`**, for the lifecycle fields the app fills in (`sessionId`, `lastRun`, etc).
|
|
134
|
+
- **Don't enable an automation that fires every minute** without warning the user. `*/5 * * * *` is usually the right floor.
|
|
135
|
+
- **Validate the cron** by running it through `cron --validate <expr>` or noting in the response that the app's scheduler will reject invalid expressions on save.
|
|
136
|
+
|
|
137
|
+
## Common pitfalls
|
|
138
|
+
|
|
139
|
+
- **Cron means local time.** Users who travel get surprises. Mention it on creation if the cadence is time-sensitive.
|
|
140
|
+
- **First fire is at the next match.** A 9am daily automation created at 10am won't fire until 9am tomorrow. Tell the user the expected next-fire time.
|
|
141
|
+
- **Body is too vague.** "Check my portfolio" produces wildly different output each fire. "Run mp portfolio retrieve --json and Slack me a 3-bullet summary of changes since yesterday" produces consistent output.
|
|
142
|
+
- **App-closed silence.** If a user complains an automation didn't fire, first thing to check: was the app actually running at the scheduled time?
|
|
143
|
+
|
|
144
|
+
## Related
|
|
145
|
+
|
|
146
|
+
- **moonpay-skill-builder** — author the underlying skill before scheduling it. Most good automations are "run this skill on a cron".
|
|
147
|
+
- **moonpay-artifact-builder** — for visual recurring reports, pair an automation that updates a JSON file with an artifact that reads it.
|
|
148
|
+
- **`schedule` skill** (cloud-side) — for one-shot future runs ("at 3pm tomorrow, do X"). Different system, persists across app closure.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: moonpay-card-onboarding
|
|
3
|
+
description: Set up a MoonAgents Card from scratch — collect identity, run KYC via Veriff, accept Baanx's Terms + Privacy + E-Sign disclosures, finalize registration, and delegate a Solana wallet for USDC spending. The conversational counterpart to the moon-agents-card Artifact's "Get started" CTA. Run this before moonpay-card-checkout if `mp card retrieve` errors with "No MoonCard account" or if the user has no delegated wallets.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# MoonAgents Card Onboarding
|
|
7
|
+
|
|
8
|
+
## Goal
|
|
9
|
+
|
|
10
|
+
Walk the user from "I want a MoonAgents Card" to "I can tap-to-pay on Solana USDC." This is a multi-step flow with real KYC, real legal acceptance, and a real on-chain delegation transaction. Don't shortcut any of it.
|
|
11
|
+
|
|
12
|
+
The Artifact (**moon-agents-card** in the MoonPay Agents desktop app) routes here via "Get started" or "Delegate wallet" CTAs depending on which stage the user is in.
|
|
13
|
+
|
|
14
|
+
## Pre-flight — figure out which stage they're at
|
|
15
|
+
|
|
16
|
+
Always run these two probes first. The answers tell you where to pick up:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
mp card retrieve --json
|
|
20
|
+
mp card onboarding check --json
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Five possible states:
|
|
24
|
+
|
|
25
|
+
| State | Detected by | Jump to step |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| Never started | `mp card retrieve` errors "No MoonCard account" + `mp card onboarding check` errors with same | **Step 1** |
|
|
28
|
+
| KYC in progress | `mp card onboarding check` returns `veriffUrl` (no `terms` block) | **Step 2** |
|
|
29
|
+
| KYC verified, terms not accepted | `check` returns `terms: { termsAndConditions, privacyPolicy, eSignConsentDisclosure }` | **Step 3** |
|
|
30
|
+
| Card created, no delegation | `mp card retrieve` succeeds, `mp card wallet list` is empty | **Step 4** |
|
|
31
|
+
| Fully ready | both succeed and `mp card wallet list` returns items | **Done** — route to `moonpay-card-checkout` |
|
|
32
|
+
|
|
33
|
+
Surface the current stage to the user so they understand where they are.
|
|
34
|
+
|
|
35
|
+
## Step 1 — Collect identity details and start onboarding
|
|
36
|
+
|
|
37
|
+
Ask the user for the required fields **one batch at a time** (don't drip out one field per turn — copy-paste-friendly):
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
- First name
|
|
41
|
+
- Last name
|
|
42
|
+
- Date of birth (YYYY-MM-DD)
|
|
43
|
+
- Country of residence (ISO 3166-1 alpha-2, e.g. US, GB, DE)
|
|
44
|
+
- Country of nationality (same format)
|
|
45
|
+
- Phone country code (numeric, e.g. 1 for US, 44 for UK)
|
|
46
|
+
- Phone number (digits only)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`mp user retrieve --json` may give you their email and name already — use that to pre-fill if available, but always read back to the user for confirmation.
|
|
50
|
+
|
|
51
|
+
Then call:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
mp card onboarding start \
|
|
55
|
+
--firstName "<first>" \
|
|
56
|
+
--lastName "<last>" \
|
|
57
|
+
--dateOfBirth "<YYYY-MM-DD>" \
|
|
58
|
+
--countryOfResidence "<XX>" \
|
|
59
|
+
--countryOfNationality "<XX>" \
|
|
60
|
+
--phoneCountryCode <code> \
|
|
61
|
+
--phoneNumber "<digits>"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Returns a Veriff KYC session URL. Surface it to the user with a click-through call to action ("Open this URL to complete identity verification: …"). The user opens it in their browser, completes Veriff's webcam + ID flow, comes back.
|
|
65
|
+
|
|
66
|
+
`mp card onboarding start` is **idempotent** — safe to call again with the same fields if the user lost the URL or the session expired. It just returns a fresh URL.
|
|
67
|
+
|
|
68
|
+
## Step 2 — Poll for KYC verification
|
|
69
|
+
|
|
70
|
+
After the user comes back, run:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
mp card onboarding check --json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Three things can come back:
|
|
77
|
+
- Still pending → `veriffUrl` again, no `terms` block. Tell the user Veriff hasn't reported back yet, wait 30s, re-check.
|
|
78
|
+
- **Rejected** → check response will indicate failed status. Direct the user to retry the Veriff session (a fresh `mp card onboarding start` returns a new URL).
|
|
79
|
+
- **Verified** → response contains a `terms` block. Jump to Step 3.
|
|
80
|
+
|
|
81
|
+
Don't auto-poll in a tight loop — KYC takes minutes, not seconds. One check, surface status, ask the user to nudge you again when they're done.
|
|
82
|
+
|
|
83
|
+
## Step 3 — Show terms, collect address, finalize
|
|
84
|
+
|
|
85
|
+
The `check` response contains live URLs Baanx records consent against. **Never hardcode legal URLs** — fetch them fresh each time and surface them to the user:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
terms.termsAndConditions — Baanx Terms of Service
|
|
89
|
+
terms.privacyPolicy — Privacy Policy
|
|
90
|
+
terms.eSignConsentDisclosure — US-only E-Sign Act Disclosure
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Show all three URLs to the user. Ask them to open each, read, and confirm they accept. Don't paraphrase the legal text — the URLs the user sees must match what Baanx records consent against.
|
|
94
|
+
|
|
95
|
+
Then ask for shipping/billing address:
|
|
96
|
+
```
|
|
97
|
+
- Address line 1
|
|
98
|
+
- Address line 2 (optional)
|
|
99
|
+
- City
|
|
100
|
+
- ZIP / postal code
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Then finalize:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
mp card onboarding finish \
|
|
107
|
+
--addressLine1 "<address>" \
|
|
108
|
+
--addressLine2 "<line2 or omit>" \
|
|
109
|
+
--city "<city>" \
|
|
110
|
+
--zip "<zip>" \
|
|
111
|
+
--acceptTerms true \
|
|
112
|
+
--acceptESign true # only for US residents; omit otherwise
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
On success, the user has a Baanx-issued virtual card. `mp card retrieve` now works. Move to Step 4.
|
|
116
|
+
|
|
117
|
+
## Step 4 — Delegate a Solana wallet
|
|
118
|
+
|
|
119
|
+
The card pulls USDC from a Solana wallet the user explicitly delegates. Two things to collect:
|
|
120
|
+
|
|
121
|
+
1. **Which local wallet** — `mp wallet list` to see options. Most users have one (e.g. `main`). If they don't, run `mp wallet create --name main --chain solana` first.
|
|
122
|
+
2. **Spending cap** — the on-chain `approve` amount. User-controlled. Recommend `500` for a starter cap; they can re-link with a higher cap later. **Don't suggest unlimited** — the cap is the blast radius if Baanx is ever compromised.
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
mp card wallet link --wallet <name> --currency USDC --amount <cap>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
This runs the 4-step dance locally: builds an SPL Approve tx, signs + broadcasts, fetches a fresh token+nonce from Baanx, signs the SIWS ownership message, registers with Baanx. The user sees the tx in their Solana wallet history.
|
|
129
|
+
|
|
130
|
+
On success, `mp card wallet list` shows the delegation. The user is fully onboarded.
|
|
131
|
+
|
|
132
|
+
## Wrap-up
|
|
133
|
+
|
|
134
|
+
Tell the user they're done and what's possible now:
|
|
135
|
+
|
|
136
|
+
> "You're set. Your MoonAgents Card is live with `$<cap>` delegated from your `<wallet>` Solana wallet. Tap the **Start shopping** button on the MoonAgents Card artifact whenever you want to spend it — it'll route through me and the **moonpay-card-checkout** skill."
|
|
137
|
+
|
|
138
|
+
## Important rules
|
|
139
|
+
|
|
140
|
+
- **Never hardcode the Veriff URL or legal URLs** — always fetch fresh from `mp card onboarding check`
|
|
141
|
+
- **Never auto-accept terms** — the user must see all three URLs and explicitly agree
|
|
142
|
+
- **Never suggest an unlimited delegation cap** — the cap is the loss ceiling if anything goes wrong
|
|
143
|
+
- **Never store the user's PII anywhere** — once you've passed it to `mp card onboarding start/finish`, drop it
|
|
144
|
+
- **Idempotency**: `mp card onboarding start` and `finish` are safe to retry with the same arguments — useful when sessions time out
|
|
145
|
+
|
|
146
|
+
## Related
|
|
147
|
+
|
|
148
|
+
- **moonpay-card-checkout** — runs purchases once onboarding is done. Routes back here if state regresses (e.g., delegation expired).
|
|
149
|
+
- **moon-agents-card** (Artifact) — visual state. Shows "Get started" / "Delegate wallet" / ready states based on what `mp card retrieve` + `mp card wallet list` return.
|
|
150
|
+
- **moonpay-auth** — if `mp` isn't logged in, the user needs to handle that first.
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: moonpay-skill-builder
|
|
3
|
+
description: Author new agent skills for the MoonPay Agents app. Use when the user wants to teach the agent a new workflow, encode a procedure they keep repeating, or wrap a CLI sequence as a single invokable skill. Skills are markdown files with YAML frontmatter that both Claude Code and Codex pick up natively. This skill defines the contract, the save location, and how to write skills that don't suck.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# MoonPay Skill Builder
|
|
7
|
+
|
|
8
|
+
A skill is a markdown file the agent reads when it decides the user's request matches the skill's description. It's not a function call — it's an instruction set the agent follows. Used well, skills turn a 12-step chat into one prompt; used badly, they're just untested documentation.
|
|
9
|
+
|
|
10
|
+
This skill is how new skills get authored.
|
|
11
|
+
|
|
12
|
+
## When to use this skill
|
|
13
|
+
|
|
14
|
+
- The user has a procedure they've walked the agent through more than twice.
|
|
15
|
+
- The user wants to share an agent workflow with their team.
|
|
16
|
+
- The user wants to wrap a `mp` CLI command sequence (or any other tool sequence) as a single invocable thing.
|
|
17
|
+
|
|
18
|
+
Don't use this skill for one-off requests or things that are already a single `mp` command — those don't need a skill.
|
|
19
|
+
|
|
20
|
+
## On-disk format
|
|
21
|
+
|
|
22
|
+
A skill is a directory. The directory name is the skill slug (kebab-case, must match the frontmatter `name`).
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
<slug>/
|
|
26
|
+
├── SKILL.md # Required. Frontmatter + body.
|
|
27
|
+
├── scripts/ # Optional. Helper scripts the skill body calls.
|
|
28
|
+
├── references/ # Optional. Long-form docs the body links to.
|
|
29
|
+
└── templates/ # Optional. Reference files the agent can read or copy.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Only `SKILL.md` is required. Most useful skills stop there.
|
|
33
|
+
|
|
34
|
+
### `SKILL.md` frontmatter
|
|
35
|
+
|
|
36
|
+
Both Claude Code and Codex are strict — only **two fields** are portable across both engines:
|
|
37
|
+
|
|
38
|
+
```yaml
|
|
39
|
+
---
|
|
40
|
+
name: my-skill-slug
|
|
41
|
+
description: One paragraph explaining (a) WHEN the agent should invoke this skill, and (b) WHAT it does. The description is the matching surface — write it like a router, not a summary.
|
|
42
|
+
---
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
| key | required | notes |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| `name` | required | kebab-case slug, matches the directory name |
|
|
48
|
+
| `description` | required | The matching text. See "Writing the description" below — this is the highest-leverage part of the skill |
|
|
49
|
+
|
|
50
|
+
**Do not add other fields** (`tags`, `category`, `version`, `author`, etc). Codex's docs explicitly state "Do not include any other fields in YAML frontmatter." Claude has its own optional fields (`allowed-tools`, `disable-model-invocation`, `model`, `effort`, `paths`, etc.) but those are Claude-specific — using them breaks portability.
|
|
51
|
+
|
|
52
|
+
For app-side metadata that the MoonPay Agents app might want (filter chips, icons, etc.), the app derives those from the skill's filesystem location, not from frontmatter. Built-in skills come from the plugin path; user-authored skills come from `.agents/skills/`. No metadata required from the skill itself.
|
|
53
|
+
|
|
54
|
+
### Save location
|
|
55
|
+
|
|
56
|
+
Write user-authored skills here:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
~/.moonpay-agents/.agents/skills/<slug>/SKILL.md
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
(The `.agents/skills/` path is Codex-native. The MoonPay Agents app symlinks `.claude/skills` → `.agents/skills` on startup so Claude Code picks them up too.)
|
|
63
|
+
|
|
64
|
+
Built-in MoonPay skills live under `~/.moonpay-agents/plugins/moonpay/skills/` and are managed by `mp plugin install/update` — don't write there.
|
|
65
|
+
|
|
66
|
+
## Writing the description
|
|
67
|
+
|
|
68
|
+
The description is the only thing the agent sees when deciding whether to invoke your skill. Write it like routing logic, not like documentation.
|
|
69
|
+
|
|
70
|
+
**Good** (specific triggers, concrete verbs, says what it does):
|
|
71
|
+
> Trade on Polymarket — search markets, buy/sell outcome shares, track positions and PnL. Use when the user names Polymarket explicitly, or wants politics, crypto, news, or general-events markets.
|
|
72
|
+
|
|
73
|
+
**Bad** (vague, no trigger words):
|
|
74
|
+
> Helps with prediction markets.
|
|
75
|
+
|
|
76
|
+
**Bad** (says what NOT to do without saying what to do):
|
|
77
|
+
> Don't use for Kalshi. Don't use for sports betting. Don't use for…
|
|
78
|
+
|
|
79
|
+
A good description answers two questions in one paragraph:
|
|
80
|
+
1. **When should the agent pick this skill?** (Specific triggers, user phrases, concrete situations.)
|
|
81
|
+
2. **What will the agent do once it picks it?** (One verb-led sentence: "search…, buy/sell…, track…")
|
|
82
|
+
|
|
83
|
+
If your description doesn't have at least two trigger phrases the user would actually say, rewrite it.
|
|
84
|
+
|
|
85
|
+
## Writing the body
|
|
86
|
+
|
|
87
|
+
The body is what the agent reads after picking the skill. It's read-only context, not executable — the agent decides what to actually do based on what the body says.
|
|
88
|
+
|
|
89
|
+
### Structure that works
|
|
90
|
+
|
|
91
|
+
```markdown
|
|
92
|
+
# <Skill Title>
|
|
93
|
+
|
|
94
|
+
One sentence: what this skill does and the one thing it's good for.
|
|
95
|
+
|
|
96
|
+
## When to use
|
|
97
|
+
|
|
98
|
+
Bullet list of concrete situations. Be specific. "When the user mentions X" beats "When relevant."
|
|
99
|
+
|
|
100
|
+
## Setup (if any)
|
|
101
|
+
|
|
102
|
+
Commands to run once before the skill's main flow. Skip the section entirely if there's no setup.
|
|
103
|
+
|
|
104
|
+
## The flow
|
|
105
|
+
|
|
106
|
+
Numbered steps. Each step:
|
|
107
|
+
- States the goal of the step in one line
|
|
108
|
+
- Shows the exact command(s) with example argv
|
|
109
|
+
- Says what to surface to the user between steps
|
|
110
|
+
|
|
111
|
+
## Important rules
|
|
112
|
+
|
|
113
|
+
Bullets of must / never. Use these for things that look optional but aren't (e.g. "Always pass --json", "Never click Pay Now").
|
|
114
|
+
|
|
115
|
+
## Related
|
|
116
|
+
|
|
117
|
+
Links to other skills the agent should bounce to.
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Body rules
|
|
121
|
+
|
|
122
|
+
- **Write commands literally**, with realistic example arguments. The agent will copy-paste them. `mp wallet list` is useful; `mp <whatever wallet command>` is not.
|
|
123
|
+
- **Don't paraphrase tool output.** If the skill processes the output of `mp foo --json`, name the actual fields (`data.items[0].balance`, not "the balance field").
|
|
124
|
+
- **Surface intermediate state to the user.** Between steps, the agent should tell the user what just happened in one line. Write that line in the skill body so the agent doesn't have to invent it.
|
|
125
|
+
- **Pause for confirmation before irreversible actions** — send money, sign tx, push to remote, click Pay. Spell out the pause in the body.
|
|
126
|
+
- **Bail to another skill** if pre-flight fails. Example: `moonpay-card-checkout` bails to `moonpay-card-onboarding` if there's no card yet.
|
|
127
|
+
|
|
128
|
+
### Body anti-patterns
|
|
129
|
+
|
|
130
|
+
- **"This skill is helpful for…"** — that's the description's job. The body is for the agent, not the user.
|
|
131
|
+
- **Explaining concepts at length.** If you find yourself writing two paragraphs of background, move it to `references/<topic>.md` and link to it.
|
|
132
|
+
- **Branching trees.** If the skill has 6 if/else paths, it's probably 2 skills.
|
|
133
|
+
- **No examples.** Every command needs at least one concrete example argv.
|
|
134
|
+
|
|
135
|
+
## Authoring flow (what the agent should do)
|
|
136
|
+
|
|
137
|
+
When the user invokes you:
|
|
138
|
+
|
|
139
|
+
1. **Ask what the skill should do** — one paragraph from the user describing the workflow, including the triggers ("when I say X").
|
|
140
|
+
2. **Propose the slug + description back to the user** for confirmation. The description is the highest-leverage part; don't move past this until the user says yes.
|
|
141
|
+
3. **Draft the body** following the structure above. Use real `mp` commands where possible — search `mp --help` if you're unsure.
|
|
142
|
+
4. **Save** to `~/.moonpay-agents/.agents/skills/<slug>/SKILL.md` (create the directory if needed).
|
|
143
|
+
5. **Show the user the saved path** and remind them they may need to restart the chat for the agent to pick up the new skill.
|
|
144
|
+
|
|
145
|
+
## Common pitfalls
|
|
146
|
+
|
|
147
|
+
- **Skill is too broad.** "moonpay-helper" with description "helps with MoonPay stuff" will never be selected reliably. Each skill should do one thing.
|
|
148
|
+
- **Skill is too narrow.** "moonpay-buy-eth-on-monday" should just be an automation, not a skill.
|
|
149
|
+
- **Skill description is the same as an existing skill.** Run `mp skill list` first; if there's overlap, edit the existing skill instead of adding a new one.
|
|
150
|
+
- **Skill calls `mp` commands that don't exist.** Run them in a shell first to confirm flags + output shape.
|
|
151
|
+
- **Skill body is a wall of prose.** The agent will read it, but the user won't review it. Keep it tight.
|
|
152
|
+
|
|
153
|
+
## Related
|
|
154
|
+
|
|
155
|
+
- **moonpay-artifact-builder** — sibling skill for authoring HTML artifacts (the visual side; this one is the procedural side).
|
|
156
|
+
- **moonpay-automation-builder** — sibling skill for scheduling existing skills on a cron.
|
|
157
|
+
- **`mp skill list`** — see what's already installed before authoring a new one.
|