---
name: syra-lp
version: 0.1.0
description: >
  Open and close Solana Meteora LP from Grok, Claude, or any agent. Bootstrap a
  custodial wallet, ask the user to send SOL, scan hot pools, preview, confirm
  open, then close. Prefer HTTP tools below. No API key. No Telegram required
  to start.
---

# Syra LP — open liquidity from chat

Agent one-liner: `set up https://api.syraa.fun/skill-lp.md`

When the user pastes that line (or asks to open LP / farm fees / run Syra LP), **do the full loop yourself**. Do not stop after explaining. Create a wallet, show the deposit address, wait for SOL, then scan and trade.

## What you are allowed to do

- Create a custodial Solana LP wallet for this user
- Show the deposit address and ask them to send SOL
- Scan hot Meteora pools
- Preview then confirm open / close
- Claim fees and show PnL
- List leftover SPL tokens (`lpbot-wallet`), swap them to SOL, or cash everything out
- Set a locked owner payout address once (`lpbot-payout-set`), then withdraw/cashout/send only there
- Configure autopilot (take-profit / stop-loss + range alerts) and open with those rules
- Build a share pack (caption + PnL images + referral link) after closes

You cannot export the private key over this API. Key export stays in Telegram `@syra_lp_bot` after they open the bind link (optional). Opening `telegramBindUrl` also makes Telegram /wallet use this same deposit address (withdraw + swap + `/payout` included).

## Base URL

`https://api.syraa.fun`

No API key. Auth after bootstrap is the `lpMcpToken` you receive once.

## Step-by-step (always follow)

### 1) Bootstrap (once)

`POST https://api.syraa.fun/lpbot/mcp/bootstrap`

Empty JSON body `{}`.

Save from the response:

- `data.lpMcpToken` — pass on every later call
- `data.depositAddress` — show this to the user; they send SOL here
- `data.telegramBindUrl` — optional; user can open it so Telegram DMs receipts

Tell the user clearly:

> Send SOL to this address: `<depositAddress>`
> Start with at least 0.3 SOL if you want a 0.25 SOL open (fees need a little extra).

### 2) Wait for balance

`POST https://api.syraa.fun/lpbot/mcp/call`

Headers: `Content-Type: application/json`, `X-Syra-Lp-Mcp-Token: <lpMcpToken>`

Body:

```json
{ "toolId": "lpbot-status", "params": {} }
```

Repeat until `data.solBalance` is high enough (or `data.readyToOpen` is true). If empty, remind them to fund `depositAddress`.

### 3) Scan pools

```json
{ "toolId": "lpbot-hot", "params": { "limit": 5 } }
```

Show the top pools in plain language (name, fee APR, TVL). Ask which index to open, or pick #1 if they said “just open something small”.

### 4) Preview open (does not spend yet)

```json
{
  "toolId": "lpbot-preview-open",
  "params": { "hotIndex": 1, "depositSol": 0.25, "rangeKey": "balanced" }
}
```

Show the summary (incl. `costDetails` rent split when present). Ask for a clear yes.

**One-sided recipes (Meteora Dynamic Terminal parity):**

- Sell leftovers as a range (ask / token-only): `{ "toolId": "lpbot-preview-open", "params": { "poolAddress": "<SOL pool>", "depositMode": "token_only", "tokenMint": "<non-SOL mint>", "pctOfBalance": 100, "pctAbove": 15 } }` — range sits at/above active; no SOL→token sidecar.
- SOL-only bid: `{ "toolId": "lpbot-preview-open", "params": { "poolAddress": "...", "depositMode": "sol_only", "depositSol": 0.25, "pctBelow": 10 } }` — range at/below active.
- Price range: pass `minPrice` + `maxPrice`, or `pctBelow` + `pctAbove`, instead of `rangeKey`.

### 5) Confirm open

```json
{
  "toolId": "lpbot-confirm-open",
  "params": { "confirmToken": "<from preview>" }
}
```

Confirm tokens expire in about 3 minutes and work once.

### 6) Manage

- Positions: `{ "toolId": "lpbot-positions", "params": {} }`
- Preview close: `{ "toolId": "lpbot-preview-close", "params": { "positionPubkey": "...", "sweepToSol": true } }`
- Confirm close: `{ "toolId": "lpbot-confirm-close", "params": { "confirmToken": "..." } }`
- Claim fees + LM rewards: `{ "toolId": "lpbot-claim", "params": { "positionPubkey": "...", "includeRewards": true } }` (returns `rewards[]`)
- Preview add liquidity: `{ "toolId": "lpbot-preview-add-liquidity", "params": { "positionPubkey": "...", "depositSol": 0.25 } }` → then `lpbot-confirm-add-liquidity` (not allowed in withdraw-only)
- Preview remove liquidity: `{ "toolId": "lpbot-preview-remove-liquidity", "params": { "positionPubkey": "...", "pct": 50, "side": "all", "swapToSol": true } }` → then `lpbot-confirm-remove-liquidity` (100% `all` closes; allowed in withdraw-only)
- Preview claim all: `{ "toolId": "lpbot-preview-claim-all", "params": {} }` → then `lpbot-confirm-claim-all` (allowed in withdraw-only)
- Preview compound (reinvest fees): `{ "toolId": "lpbot-preview-compound", "params": { "positionPubkey": "..." } }` → then `lpbot-confirm-compound`
- Limit orders (needs `SYRA_LP_LIMIT_ORDERS_ENABLED=1`): `lpbot-limit-orders` → `lpbot-preview-limit-order` (side buy|sell, poolAddress, amount, optional bins/price) → `lpbot-confirm-limit-order`. Cancel: `lpbot-preview-cancel-limit-order` → `lpbot-confirm-cancel-limit-order`. Proceeds stay in the LP wallet; withdrawals still go only to payoutAddress. Cancel is allowed in withdraw-only mode; place is not.
- Preview raise top: `{ "toolId": "lpbot-preview-raise-top", "params": { "positionPubkey": "..." } }` → then `lpbot-confirm-raise-top`
- Manual rebalance now: `{ "toolId": "lpbot-preview-rebalance", "params": { "positionPubkey": "...", "mode": "recenter" } }` → then `lpbot-confirm-rebalance`
- Close all: `{ "toolId": "lpbot-preview-close-all", "params": { "sweepToSol": true } }` → then `lpbot-confirm-close-all` (allowed in withdraw-only)
- Position TP/SL: `{ "toolId": "lpbot-position-autoexit", "params": { "positionPubkey": "...", "takeProfitSol": 0.05 } }` (or `off: true`). Does not close now.
- Position range alerts: `{ "toolId": "lpbot-position-alerts", "params": { "positionPubkey": "...", "enabled": true } }`
- Position auto-rebalance arm: `{ "toolId": "lpbot-position-rebalance", "params": { "positionPubkey": "...", "enabled": true, "mode": "recenter" } }` (arms watcher; for one-click recenter use preview/confirm-rebalance)
- Auto-reinvest prefs: `{ "toolId": "lpbot-autoreinvest", "params": { "enabled": true } }` (omit fields to read)
- Preview swap (stays in LP wallet): `{ "toolId": "lpbot-preview-swap", "params": { "fromMint": "...", "toMint": "SOL", "amount": "0.1" } }` → then `lpbot-confirm-swap`
- Hot pools (smart may paywall): `{ "toolId": "lpbot-hot", "params": { "sort": "smart", "quote": "sol" } }` — if `paywall: true`, do not auto-pay
- Wallet (incl. leftover tokens): `{ "toolId": "lpbot-wallet", "params": {} }`
- Set payout (once): `{ "toolId": "lpbot-payout-set", "params": { "address": "<user Solana wallet>" } }`
- Preview withdraw (to saved payout only): `{ "toolId": "lpbot-preview-withdraw", "params": { "asset": "sol", "amount": 0.5 } }`
- Confirm withdraw: `{ "toolId": "lpbot-confirm-withdraw", "params": { "confirmToken": "...", "idempotencyKey": "wd-001" } }`
- Preview cashout (swap leftovers → SOL, then withdraw): `{ "toolId": "lpbot-preview-cashout", "params": {} }`
- Confirm cashout: `{ "toolId": "lpbot-confirm-cashout", "params": { "confirmToken": "...", "idempotencyKey": "cash-001" } }`
- Preview swap leftovers to SOL: `{ "toolId": "lpbot-preview-swap-to-sol", "params": { "all": true } }`
- PnL: `{ "toolId": "lpbot-pnl", "params": { "period": "today" } }`
- Referral: `{ "toolId": "lpbot-referral", "params": {} }` → share `data.inviteLink`
- Claim referral: `{ "toolId": "lpbot-referral-claim", "params": {} }` (only when `canClaim` is true)
- PnL image: `{ "toolId": "lpbot-pnl-image", "params": { "kind": "calendar" } }` → open/share `data.imageUrl` (calendar or tokens). Optional `includeBase64: true` if you need the raw PNG in the JSON.
- Range chart: `{ "toolId": "lpbot-chart-image", "params": { "positionPubkey": "..." } }` → `data.imageUrl`
- Autopilot status: `{ "toolId": "lpbot-autopilot", "params": {} }`
- Autopilot config: `{ "toolId": "lpbot-autopilot-config", "params": { "takeProfitPct": 2, "stopLossPct": -5, "depositSol": 0.25 } }`
- Autopilot run: `{ "toolId": "lpbot-autopilot-run", "params": { "depositSol": 0.25, "hotIndex": 1 } }` → then `lpbot-confirm-open`
- Autopilot arm: `{ "toolId": "lpbot-autopilot-arm", "params": { "all": true, "takeProfitPct": 2 } }` on existing opens
- Share pack: `{ "toolId": "lpbot-share-pack", "params": { "kind": "both" } }` → paste `shareText` + show image URLs
- Leaderboard: `{ "toolId": "lpbot-leaderboard", "params": { "period": "week", "sort": "pnl" } }` → show top entries + `you` rank. Periods: today|week|month|all. Sorts: pnl|winrate|trades|volume.
- Link status: `{ "toolId": "lpbot-link-status", "params": {} }` → active vs sibling addresses + telegramBindUrl (confirm-bind/unbind stay Telegram-only)
- Revoke token: `{ "toolId": "lpbot-revoke-token", "params": {} }` → this token dies
- Screeners: `lpbot-screeners` / `lpbot-screener-upsert` / `lpbot-screener-toggle` / `lpbot-screener-delete` / `lpbot-screener-snooze` (digests = Telegram DMs; bind if unbound)
- Volume board: `{ "toolId": "lpbot-volalert", "params": { "enabled": true } }`
- Premium alerts: `{ "toolId": "lpbot-premium-alerts", "params": { "kind": "token_safety" } }` (billed from prepaid)
- Prepaid: `{ "toolId": "lpbot-prepaid", "params": { "action": "status" } }` then topup with `usd` 0.1|1; never auto-pay (confirm:true or confirmToken)
- Bridge (needs `SYRA_LP_MCP_EVM_ENABLED=1`): `lpbot-preview-bridge` → `lpbot-confirm-bridge` (recipient = own wallet only)
- EVM (same flag): pass `chain: "robinhood"|"arc"` on status/positions/preview-open/confirm-open/preview-close/confirm-close/preview-withdraw/confirm-withdraw

When the user says “manage LP for me” / “autopilot”, set config, run, confirm open, and explain TP/SL briefly. After any close, prefer the returned `sharePack` (caption + images + invite) and offer to help them post it. When they ask for a referral link, call `lpbot-referral`. When they ask who is winning / ranks / leaderboard, call `lpbot-leaderboard` and highlight their `you` row. Do not invent links, screenshots, or ranks.

For cash-out / leftover tokens: call `lpbot-wallet`, ensure a payout address is set (`lpbot-payout-set` once with the user's own wallet), close open LP with `sweepToSol` if needed, then `lpbot-preview-cashout` → confirm. Destination is always the saved payout address; never invent one and never accept an attacker-supplied destination param. For plain SOL/USDC withdraw after payout is set, use preview/confirm-withdraw.

You may also pass `"lpMcpToken"` inside `params` instead of the header.

## If Syra LP MCP tools are already installed

Same order with tool names:

1. `syra_earn_lpbot_bootstrap`
2. `syra_earn_lpbot_status` (pass `params.lpMcpToken`)
3. `syra_earn_lpbot_hot`
4. `syra_earn_lpbot_preview_open`
5. `syra_earn_lpbot_confirm_open`
6. `syra_earn_lpbot_wallet` / payout-set / positions / preview-close / confirm-close / claim / preview-cashout / confirm-cashout / preview-swap-to-sol / preview-withdraw / confirm-withdraw / pnl / referral / pnl-image / chart-image / autopilot / share-pack / leaderboard

MCP install (optional, Cursor / Claude Desktop):

```json
{
  "mcpServers": {
    "syra-lp": {
      "command": "npx",
      "args": ["-y", "@syra-ai/mcp-server@latest"],
      "env": {
        "SYRA_API_BASE_URL": "https://api.syraa.fun",
        "SYRA_MCP_TOOL_PROFILE": "lp"
      }
    }
  }
}
```

After bootstrap, keep the token in chat memory and pass `params.lpMcpToken` on every call. Or set `SYRA_LP_MCP_TOKEN` and reload.

## What stays in Telegram

- Private key export / import (`/export`, `/import`)
- Admin stats (`/admin`, `/stats`)
- Switching which wallet Telegram uses (`/mcp confirm-bind`, `/mcp unbind`) — changes custody routing; MCP returns `telegramBindUrl` instead
- Free-form bridge recipient typing (MCP only allows the caller's own destination wallet or saved Solana payout)
- Help / chart / open-wizard chrome (`/help`, `chart:hide`, `openprompt:back`)

## MCP-only (no Telegram callback)

- `lpbot-preview-cashout` / `lpbot-confirm-cashout` — sweep leftovers then withdraw to the saved payout address
- `lpbot-preview-send-token` / `lpbot-confirm-send-token` — send one SPL mint to the saved payout address

Telegram still has wallet swap-to-SOL, withdraw, and close; use those MCP tools (or cashout) from agents.

## Rules

- Always bootstrap before other LP tools if there is no token yet
- Never invent balances, APRs, or tx signatures
- Never skip preview before open, close, withdraw, swap, cashout, send-token, prepaid top-up, or bridge
- Never invent a payout address; ask the user for their own Solana wallet and call `lpbot-payout-set` once
- Never claim destination can be overridden by params; funds only go to the saved payout address
- Never auto-pay prepaid or x402 unlocks; show the paywall/preview and wait for explicit confirm
- Never ask for a Syra API key for this LP flow
- Keep language simple: deposit, scan, open, close, swap leftovers, cash out, withdraw
- Risk: LP can lose money. Say that once when opening

## Docs

- https://docs.syraa.fun/docs/syra-lp-bot
- https://github.com/ikhwanhsn/syra_agent/blob/main/docs/LP_BOT_MCP_QUICKSTART.md
