{
  "name": "yobo",
  "title": "YOBO, You Only Build Once",
  "version": "1.0.0",
  "description": "An agentic launchpad and project builder on Robinhood Chain. One line of text becomes a token, a bonding curve and a project page whose plan is written to the chain in the same transaction. Every tool takes one object and returns one.",
  "site": "https://yobo.best",
  "shape": "mcp-tools",
  "conventions": {
    "errors": "A tool that cannot answer returns {\"error\":\"<code>\",\"message\":\"...\"}; over MCP the result carries isError:true. Codes: not_deployed, chain_unreachable, not_found, not_a_curve, bad_*, text_required, text_too_long.",
    "numbers": "Wei and token base units travel as decimal strings. Fields ending in Eth or Units are the same value in human units. progress is a fraction 0..1.",
    "determinism": "yobo_design is a pure function of the text: the same words design the same project, byte for byte, in the browser, the CLI and here.",
    "keys": "No tool ever holds a private key. yobo_calldata returns a transaction for you to sign; the optional yobo_build_send runs cast with an operator-owned keystore.",
    "units": "HTTP quote takes wei / base units; the CLI and MCP quote take ETH / tokens as decimal strings (raw:true switches to base units)."
  },
  "transport": {
    "http": {
      "base": "https://yobo.best/api",
      "endpoints": {
        "status": "GET /api/status",
        "spec": "GET /api/spec?text=  |  POST /api/spec {text}",
        "build": "POST /api/build {text}  (Claude-designed spec; 501 when the server has no key)",
        "calldata": "POST /api/calldata {text | spec | params, openingBuyEth?, creatorFeeRecipient?, minTokensOut?}",
        "builds": "GET /api/builds?limit=&offset=",
        "project": "GET /api/project?token=0x...",
        "quote": "GET /api/quote?curve=0x...&side=buy|sell&amount=<wei | token base units>",
        "rpc": "POST /api/rpc  (read-only JSON-RPC proxy to Robinhood Chain)"
      },
      "cors": "Access-Control-Allow-Origin: * on every read route."
    },
    "cli": {
      "get": "curl -sO https://yobo.best/cli/yobo.mjs",
      "run": "node yobo.mjs design \"a chalk drawing game\"",
      "commands": [
        "design",
        "logo",
        "calldata",
        "build",
        "builds",
        "project",
        "quote",
        "status",
        "mcp",
        "manifest"
      ],
      "node": ">=20, zero dependencies; build needs Foundry's cast on PATH"
    },
    "mcp": {
      "kind": "stdio",
      "command": "node /path/to/yobo/cli/yobo.mjs mcp",
      "claudeCode": "claude mcp add yobo -- node /path/to/yobo/cli/yobo.mjs mcp",
      "protocolVersion": "2025-06-18",
      "optionalTools": [
        "yobo_build_send (only when YOBO_KEYSTORE and YOBO_PASSWORD_FILE are set for the server)"
      ]
    }
  },
  "deployment": {
    "status": "live",
    "pending": false,
    "network": "Robinhood Chain",
    "chainId": 4663,
    "rpc": "https://yobo.best/api/rpc",
    "publicRpc": "https://rpc.mainnet.chain.robinhood.com",
    "explorer": "https://robinhoodchain.blockscout.com",
    "deployBlock": 55772731,
    "factory": "0x54bf38e4f860b62c91cc3ea8a46800270d11577c",
    "curveDeployer": "0x11373b01ef3ef421dc4e349d1ca7899bf668fd9b",
    "migrator": "0x29a16fab9aaae7bedf13565ed95ad304fb5ec643",
    "locker": "0x11c746e6006f6091e8caaba765bd293396e2b389",
    "weth": "0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73",
    "multicall3": "0xcA11bde05977b3631167028862bE2a173976CA11",
    "token": "",
    "note": "Every address above was read back from the chain by tools/verify-deployment.js."
  },
  "tools": [
    {
      "name": "yobo_design",
      "title": "Design a build",
      "description": "Turn one line of text into a build spec: name, symbol, description, tagline, blueprint (kind, what, how, milestones, links), logo seed and colours, plus the exact BuildParams the factory takes. Deterministic and offline: the same text designs the same project everywhere.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "description": "What you want to build. One line to a paragraph, up to 2000 characters. \"$TICKER\" sets the symbol, \"called X\" sets the name."
          }
        },
        "required": [
          "text"
        ],
        "additionalProperties": false
      },
      "returns": "{spec, params, problems:[]}",
      "example": "{\"text\":\"a chalk drawing game called Chalk Rocket $ROCKET\"}",
      "onChain": "off chain, a pure function"
    },
    {
      "name": "yobo_logo",
      "title": "Draw the sticker",
      "description": "The generated logo as a standalone SVG string: a board tile, a chalk glyph and a coloured box with the symbol. Give text (the design is derived from it) or a seed plus a symbol.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "description": "The build text; the seed, colours and glyph come from it."
          },
          "seed": {
            "type": "string",
            "description": "A \"yobo:1:<8 hex>\" seed, as stored in a token's logo field."
          },
          "symbol": {
            "type": "string",
            "description": "The symbol to print in the box when a seed is given."
          }
        },
        "additionalProperties": false
      },
      "returns": "{seed, symbol, svg}",
      "example": "{\"text\":\"a chalk drawing game\"}",
      "onChain": "off chain; the chain stores only the seed"
    },
    {
      "name": "yobo_calldata",
      "title": "Prepare the build transaction",
      "description": "The exact transaction that builds the project: YoboFactory.build(params) with value = build fee + opening buy. Returns {to, data, value, chainId, params, cast}. Sign it with your own key; nothing here ever holds one. Answers not_deployed until the factory is on chain.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "description": "What you want to build."
          },
          "openingBuyEth": {
            "type": "string",
            "description": "Optional opening buy in ETH, for example \"0.01\". Added to the value."
          },
          "creatorFeeRecipient": {
            "type": "string",
            "description": "Optional 0x address that receives the creator half of trade fees. Default: the sender."
          },
          "minTokensOut": {
            "type": "string",
            "description": "Optional slippage floor for the opening buy, in token base units. Default 0."
          }
        },
        "required": [
          "text"
        ],
        "additionalProperties": false
      },
      "returns": "{to, data, value, chainId, buildFeeWei, openingBuyWei, params, cast}",
      "example": "{\"text\":\"a chalk drawing game\",\"openingBuyEth\":\"0.01\"}",
      "onChain": "a transaction you send: YoboFactory.build"
    },
    {
      "name": "yobo_builds",
      "title": "List the builds",
      "description": "Every build on the factory, newest first, read live from the chain: token, curve, creator, name, symbol, logo, tagline, progress (0..1), ethRaised, price, graduated, migrated, url.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "1 to 100, default 24."
          },
          "offset": {
            "type": "integer",
            "description": "Skip this many newest builds. Default 0."
          }
        },
        "additionalProperties": false
      },
      "returns": "{count, limit, offset, builds:[{id, token, curve, creator, builtAt, name, symbol, logo, description, tagline, kind, progress, ethRaised, ethRaisedEth, price, priceEth, graduated, migrated, url}]}",
      "example": "{\"limit\":10}",
      "onChain": "eth_call through Multicall3"
    },
    {
      "name": "yobo_project",
      "title": "Read one build",
      "description": "One build by token address: the listing fields plus the parsed blueprint (what, how, milestones, links) and the whole curve state (tokens sold, ETH raised, graduation target, fees, pool amounts).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "The token address, 0x + 40 hex."
          }
        },
        "required": [
          "token"
        ],
        "additionalProperties": false
      },
      "returns": "{...build, blueprint:{kind, tagline, what, how, milestones, links}, curveState:{...}, explorer:{token, curve}}",
      "example": "{\"token\":\"0x0000000000000000000000000000000000000000\"}",
      "onChain": "eth_call through Multicall3"
    },
    {
      "name": "yobo_quote",
      "title": "Quote a trade",
      "description": "The curve's own quote, fees included. amount is human: ETH for a buy (\"0.01\"), tokens for a sell (\"1000\"); pass raw:true to give wei or token base units instead.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "curve": {
            "type": "string",
            "description": "The curve address, 0x + 40 hex."
          },
          "side": {
            "type": "string",
            "enum": [
              "buy",
              "sell"
            ]
          },
          "amount": {
            "type": "string",
            "description": "ETH in for a buy, tokens in for a sell. Decimal string."
          },
          "raw": {
            "type": "boolean",
            "description": "amount is already in wei / token base units."
          }
        },
        "required": [
          "curve",
          "side",
          "amount"
        ],
        "additionalProperties": false
      },
      "returns": "{ok, curve, token, side, amount, price, progress, graduated, tokensOut | ethOut, fee, ethUsed}",
      "example": "{\"curve\":\"0x0000000000000000000000000000000000000000\",\"side\":\"buy\",\"amount\":\"0.01\"}",
      "onChain": "eth_call: quoteBuy / quoteSell"
    },
    {
      "name": "yobo_status",
      "title": "Where things stand",
      "description": "Chain id, whether the factory is deployed and where, the RPC in use and the latest block. Ask this first.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "returns": "{name, version, chainId, deployed, factory, rpc, block, site}",
      "example": "{}",
      "onChain": "eth_blockNumber"
    }
  ]
}
