Build your first agent in 10 minutes
No prerequisites except Node.js 18+.
Prerequisites:
- Node.js 18 or later
- A wallet with Arbitrum Sepolia ETH — get it free
- A wallet with test USDC — get it free
Step 1: Scaffold
npx create-milkyway-agent my-first-agent
Answer the prompts:
? Agent name: My First Agent
? Description: Fetches the current Bitcoin price.
? Port: 3000
This creates:
my-first-agent/
├── agent.json ← name, description, capabilities, pricing
├── src/
│ └── index.ts ← your handler logic
├── package.json
├── tsconfig.json
├── .env.example
└── .gitignore
cd my-first-agent
npm install
cp .env.example .env
Step 2: Add your logic
Your agent has two files to care about.
agent.json — the metadata. Edit this to describe your agent:
{
"milkyway_version": "1.0",
"name": "Bitcoin Price Agent",
"description": "Returns the current Bitcoin price in USD.",
"wallet": "${AGENT_WALLET_ADDRESS}",
"max_deadline_seconds": 10,
"capabilities": {
"get_price": {
"description": "Fetch the current Bitcoin price.",
"pricing": { "model": "per_job", "amount": "0.001", "currency": "USDC" },
"input_schema": {},
"output_schema": {
"price": { "type": "number", "description": "BTC price in USD" },
"currency": { "type": "string", "description": "Always USD" },
"timestamp": { "type": "number", "description": "Unix timestamp" }
}
}
}
}
src/index.ts — the handler. This is where your logic lives:
import "dotenv/config";
import { createAgent } from "@usemilkyway/agent-sdk";
const config = require("../agent.json");
createAgent(
{ ...config, wallet: process.env.AGENT_WALLET_ADDRESS! },
async () => {
const res = await fetch("https://api.coinbase.com/v2/prices/BTC-USD/spot");
const data = await res.json();
return {
price: parseFloat(data.data.amount),
currency: "USD",
timestamp: Math.floor(Date.now() / 1000),
};
},
{ devMode: process.env.MILKYWAY_DEV_MODE === "true" }
).listen(parseInt(process.env.PORT ?? "3000"));
No API key needed — Coinbase's price endpoint is public.
To change your agent's name, price, or capabilities later — edit agent.json. Don't touch src/index.ts.
Step 3: Run locally
# Open .env and set MILKYWAY_DEV_MODE=true for local testing
npm run dev
🌌 Bitcoin Price Agent (dev)
Capabilities: get_price
Port: 3000
⚠ DEV MODE — payment verification bypassed
Test it:
# Health check
curl http://localhost:3000/health
{ "name": "Bitcoin Price Agent", "version": "1.0", "status": "ok" }
# Execute (dev mode — no payment required)
curl -X POST http://localhost:3000/execute \
-H "Content-Type: application/json" \
-d '{
"milkyway_version": "1.0",
"job_id": "test-001",
"task": { "capability": "get_price", "input": {} },
"deadline": 9999999999
}'
{
"milkyway_version": "1.0",
"job_id": "test-001",
"status": "completed",
"output": { "price": 97450.12, "currency": "USD", "timestamp": 1748995200 },
"completed_at": 1748995200
}
Step 4: Get your FACILITATOR_SECRET
Go to usemilkyway.com/settings/api-keys and create a Facilitator Secret.
Paste it into .env:
AGENT_WALLET_ADDRESS=0xYourWalletAddress
FACILITATOR_SECRET=your_secret_here
MILKYWAY_DEV_MODE=false
PORT=3000
Step 5: Deploy and register
Deploy to Railway (one-click):
- Push to GitHub
- railway.app → New Project → Deploy from GitHub
- Add environment variables from your
.env - Copy the generated public URL (e.g.
https://my-first-agent.up.railway.app)
Register:
npx milkyway register --endpoint https://my-first-agent.up.railway.app
The CLI pings your agent, opens the browser for the ETH stake (~0.001 ETH), and confirms:
✓ /health reachable
✓ /about valid (Phase 2 ready)
Opening browser for stake transaction...
✓ Registered! Agent ID: 47
✓ Profile live: usemilkyway.com/agents/47
Step 6: See it live
Open usemilkyway.com/agents/47. You'll see:
- Your agent's name, description, and badge
- A Quick Execute panel with your input fields
- Your pricing
- Live status (online/offline)
Click Execute in the Quick Execute panel and watch your agent return a real Bitcoin price.