@candledottv/mcp 0.10.4 → 0.10.6
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/README.md +65 -19
- package/dist/index.js +1037 -67
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# @candledottv/mcp
|
|
2
2
|
|
|
3
3
|
An MCP (Model Context Protocol) server for the Candle agent rail. It exposes Candle's REST API as
|
|
4
|
-
twenty tools over stdio, so an MCP-capable agent can launch tokens (optionally seeded with a dev
|
|
4
|
+
twenty-nine tools over stdio, so an MCP-capable agent can launch tokens (optionally seeded with a dev
|
|
5
5
|
buy in the same call), trade, convert between base assets (including across chains), read market
|
|
6
6
|
and feed data, report on-chain activity, and check an agent profile without hand-rolling HTTP
|
|
7
7
|
calls.
|
|
8
8
|
|
|
9
9
|
## Try it without a key
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Six tools are read-only and need nothing but `CANDLE_API_URL` (which already defaults to
|
|
12
12
|
production): `candle_get_market`, `candle_get_feed`, `candle_token_forensics`,
|
|
13
|
-
`candle_get_agent_profile`, and `
|
|
14
|
-
server with no `env` block at all and those
|
|
13
|
+
`candle_get_agent_profile`, `candle_resolve_token` and `candle_get_plans`. Install the
|
|
14
|
+
server with no `env` block at all and those six work immediately:
|
|
15
15
|
|
|
16
16
|
```json
|
|
17
17
|
{
|
|
@@ -31,11 +31,11 @@ Environment below -- or skip env editing entirely: install the Candle CLI
|
|
|
31
31
|
environment.
|
|
32
32
|
|
|
33
33
|
`CANDLE_MCP_TOOLS` (optional) is a comma-separated allowlist of tool names; only those register.
|
|
34
|
-
Unset means all twenty. An unknown name fails startup with the valid names in the message, rather
|
|
34
|
+
Unset means all twenty-nine. An unknown name fails startup with the valid names in the message, rather
|
|
35
35
|
than silently registering the wrong surface. `candle mcp --read-only` / `--tools` set this for
|
|
36
36
|
you.
|
|
37
37
|
|
|
38
|
-
Most tools are a thin wrapper: a one-request mapping onto
|
|
38
|
+
Most tools are a thin wrapper: a one-request mapping onto Candle's REST API
|
|
39
39
|
(`POST /api/v1/launch/headless`, `GET /api/v1/markets/:chain/:mint`, `GET /api/v1/markets/feed`,
|
|
40
40
|
`POST /api/v1/activity/report`, `GET /api/v1/users/:idOrWallet/agent`) that hands the response body
|
|
41
41
|
straight back to the caller, unchanged, error responses included. `candle_trade` and
|
|
@@ -48,7 +48,8 @@ Both take decimal amounts, never raw base units, and resolve the scale themselve
|
|
|
48
48
|
- A `candle_trade` **buy** is denominated in the token's OWN quote asset, whatever it was launched
|
|
49
49
|
against (SOL for a SOL-launched token, USDC or CNDL for those quote pairs). The tool reads the
|
|
50
50
|
market first and converts against its `quoteDecimals`; the `quoteAsset` field applies only to a
|
|
51
|
-
mint Candle never launched, the
|
|
51
|
+
mint Candle never launched, the path traded through Jupiter (buying needs Pro or Max; selling
|
|
52
|
+
works on any plan). A
|
|
52
53
|
**sell** is denominated in tokens and converts against the market's own `decimals`.
|
|
53
54
|
- A `candle_launch_and_seed` `devBuy` is denominated in the quote asset that launch selects, since
|
|
54
55
|
there the caller genuinely picks the new token's quote pair: `quoteAsset` if given, otherwise
|
|
@@ -56,11 +57,11 @@ Both take decimal amounts, never raw base units, and resolve the scale themselve
|
|
|
56
57
|
|
|
57
58
|
For a full walkthrough of `candle_launch_and_seed` and `candle_trade`, including the keyless read
|
|
58
59
|
tools, getting a key, funding the embedded wallet, and idempotent retries, see
|
|
59
|
-
|
|
60
|
+
[Candle MCP server](https://docs.candle.tv/developers/mcp-server).
|
|
60
61
|
|
|
61
62
|
## Environment
|
|
62
63
|
|
|
63
|
-
- `CANDLE_API_URL` -- base URL of the Candle API. Defaults to `https://api.alpha.candle.tv
|
|
64
|
+
- `CANDLE_API_URL` -- base URL of the Candle API. Defaults to `https://api.alpha.candle.tv`, production. Set it to
|
|
64
65
|
`http://localhost:3001` when developing against a local API. A cleartext `http://` URL pointing
|
|
65
66
|
at a NON-loopback host is refused at startup, since every write tool sends `x-api-key`; loopback
|
|
66
67
|
(`localhost`, `127.0.0.0/8`, `::1`) needs no opt-in.
|
|
@@ -68,13 +69,18 @@ tools, getting a key, funding the embedded wallet, and idempotent retries, see
|
|
|
68
69
|
non-loopback host. For a trusted local endpoint that is not loopback, such as a devcontainer
|
|
69
70
|
reaching its host; not for anything that leaves the machine.
|
|
70
71
|
- `CANDLE_AGENT_API_KEY` -- an agent API key (`cndl_live_...` / `cndl_test_...`), issued from a
|
|
71
|
-
Candle account's agent settings page. Required by every tool except the
|
|
72
|
+
Candle account's agent settings page. Required by every tool except the six read-only ones
|
|
72
73
|
listed above, which includes the account-scoped reads (`candle_get_wallets`,
|
|
73
|
-
`candle_execution_status`, `candle_get_operation`) as well as the writes; those
|
|
74
|
+
`candle_execution_status`, `candle_get_operation`) as well as the writes; those six
|
|
74
75
|
work without it, so the server is useful the moment it is installed and only asks for a key when
|
|
75
76
|
you try to write. `candle_trade` additionally needs the key's `swap:write` scope server-side,
|
|
76
|
-
which is opt-in only and never granted by omission, see
|
|
77
|
-
|
|
77
|
+
which is opt-in only and never granted by omission, see
|
|
78
|
+
[Agent access](https://docs.candle.tv/developers/agent-access).
|
|
79
|
+
- `CANDLE_KEY_SIGNER_PEM_FILE` -- the perps write tools only: the path to the key signer's PEM
|
|
80
|
+
(`candle tee signer new --out <pem>` writes one). The relay's authorization is signed with it;
|
|
81
|
+
without it those tools refuse before anything is built.
|
|
82
|
+
- `CANDLE_HYPERLIQUID_BUILDER` / `CANDLE_HYPERLIQUID_NETWORK` -- the perps tools: pin Candle's
|
|
83
|
+
Hyperliquid builder address for the pre-sign check, and set `testnet` to trade testnet.
|
|
78
84
|
- `CANDLE_API_KEY` -- alias for `CANDLE_AGENT_API_KEY`, the same variable name the Candle CLI uses
|
|
79
85
|
for this credential. Set either one; if both are set, `CANDLE_AGENT_API_KEY` takes precedence.
|
|
80
86
|
|
|
@@ -88,6 +94,7 @@ tools, getting a key, funding the embedded wallet, and idempotent retries, see
|
|
|
88
94
|
| `candle_token_forensics` | Deployer history, deploy-window buyers, sourced token safety flags | `GET /api/v1/markets/:chain/:mint/forensics` | none |
|
|
89
95
|
| `candle_report_activity` | Report on-chain activity | `POST /api/v1/activity/report` | `CANDLE_AGENT_API_KEY` |
|
|
90
96
|
| `candle_get_agent_profile` | Get an agent profile | `GET /api/v1/users/:idOrWallet/agent` | none |
|
|
97
|
+
| `candle_get_plans` | Plans: prices, fees, limits and what each can do, as JSON and a Markdown table | `GET /api/v1/agent/plans` | none |
|
|
91
98
|
| `candle_trade` | Buy or sell a token | Reads the market for its decimals (or wallet balance, for a percent sell) then `POST /api/v1/trade/agent/build` | `CANDLE_AGENT_API_KEY` (`swap:write`) |
|
|
92
99
|
| `candle_launch_and_seed` | Launch a token and seed it | `POST /api/v1/launch/headless` (or `/dry-run`), then a follow-up `GET /api/v1/markets/:chain/:mint` | `CANDLE_AGENT_API_KEY` |
|
|
93
100
|
| `candle_swap` | Swap between base assets | `POST /api/v1/agent/swap` | `CANDLE_AGENT_API_KEY` (`swap:write`) |
|
|
@@ -97,11 +104,19 @@ tools, getting a key, funding the embedded wallet, and idempotent retries, see
|
|
|
97
104
|
| `candle_get_wallets` | The account's embedded wallets, one per chain, with delegation state | `GET /api/v1/agent/wallets/embedded` | `CANDLE_AGENT_API_KEY` |
|
|
98
105
|
| `candle_get_profile_wallets` | Which wallets an agent profile may spend from, and whether it is scoped | `GET /api/v1/agent/keys/:prefix/wallets` | `CANDLE_AGENT_API_KEY` |
|
|
99
106
|
| `candle_set_profile_wallets` | Replace the wallets an agent profile may spend from | `PUT /api/v1/agent/keys/:prefix/wallets` | `CANDLE_AGENT_API_KEY` |
|
|
100
|
-
| `candle_get_profile_pnl` | An agent profile's
|
|
107
|
+
| `candle_get_profile_pnl` | An agent profile's share of the account's P&L, the console's figures to the cent: realized on its sales, fees, and the open positions that belong to it at cost basis, marked at current prices (unpriced positions counted, not zeroed), with `totalUsd`, the closed positions as made, lost and partial sells (`closed`), dust flagged and counted apart (`openPositionsExDust`), split by wallet (`pnl.byWallet`, summing to the total) and by chain (`pnl.byChain`), with `chain` and `wallet` on every position | `GET /api/v1/agent/keys/:prefix/pnl` | `CANDLE_AGENT_API_KEY` |
|
|
101
108
|
| `candle_get_profile_trades` | An agent profile's orders, fills, fees and transaction hashes | `GET /api/v1/agent/keys/:prefix/trades` | `CANDLE_AGENT_API_KEY` |
|
|
102
109
|
| `candle_get_portfolio` | What the account's embedded and TEE wallets hold on Solana and Hood (Hood in `hood`), with prices; unpriced holdings say why, never zero | `GET /api/v1/agent/portfolio` | `CANDLE_AGENT_API_KEY` (`account:read`) |
|
|
103
110
|
| `candle_execution_status` | One call before trading: wallets to spend from, tier, and whether trading is possible | Composes the wallet and tier reads | `CANDLE_AGENT_API_KEY` |
|
|
104
111
|
| `candle_get_operation` | Look up a trade or launch by the id its write used, and whether it landed | `GET /api/v1/trade/agent/jobs/:clientId` or `/api/v1/launch/headless/jobs/:clientId` | `CANDLE_AGENT_API_KEY` |
|
|
112
|
+
| `candle_perps_setup` | Approve Candle's Hyperliquid builder fee once; report the account's mode and balance | `POST /api/v1/agent/perps/setup`, then relay sign and Hyperliquid submit | `CANDLE_AGENT_API_KEY` (`perps:write`), `CANDLE_KEY_SIGNER_PEM_FILE` |
|
|
113
|
+
| `candle_perps_open` | Open or add to a perps position, with optional take-profit and stop-loss | `POST /api/v1/agent/perps/open`, checked here, relay-signed, submitted to Hyperliquid | `CANDLE_AGENT_API_KEY` (`perps:write`), `CANDLE_KEY_SIGNER_PEM_FILE` |
|
|
114
|
+
| `candle_perps_close` | Close all or part of a perps position, reduce-only | `POST /api/v1/agent/perps/close`, the same | `CANDLE_AGENT_API_KEY` (`perps:write`), `CANDLE_KEY_SIGNER_PEM_FILE` |
|
|
115
|
+
| `candle_perps_cancel` | Cancel a perps order Candle built, by cloid | `POST /api/v1/agent/perps/cancel`, the same | `CANDLE_AGENT_API_KEY` (`perps:write`), `CANDLE_KEY_SIGNER_PEM_FILE` |
|
|
116
|
+
| `candle_perps_leverage` | Set a market's leverage and margin mode | `POST /api/v1/agent/perps/leverage`, the same | `CANDLE_AGENT_API_KEY` (`perps:write`), `CANDLE_KEY_SIGNER_PEM_FILE` |
|
|
117
|
+
| `candle_perps_deposit` | Deposit onto the key's Hyperliquid account through Relay, from its Solana or Hood TEE wallet | `POST /api/v1/agent/perps/deposit`, checked here, relay-signed, `POST /api/v1/agent/perps/deposit/submit` | `CANDLE_AGENT_API_KEY` (`swap:write`), `CANDLE_KEY_SIGNER_PEM_FILE` |
|
|
118
|
+
| `candle_perps_orders` | Open Hyperliquid orders and every action Candle built | `GET /api/v1/agent/perps/orders` | `CANDLE_AGENT_API_KEY` |
|
|
119
|
+
| `candle_perps_positions` | Perps positions and account value, read live | `GET /api/v1/agent/perps/positions` | `CANDLE_AGENT_API_KEY` |
|
|
105
120
|
|
|
106
121
|
### Transfers and sweeps
|
|
107
122
|
|
|
@@ -118,13 +133,13 @@ explicitly. Assets with nothing spendable report `empty`; a failed asset never s
|
|
|
118
133
|
## Errors
|
|
119
134
|
|
|
120
135
|
This package never reinterprets an error body, and that body is not one uniform shape across all
|
|
121
|
-
twenty tools:
|
|
136
|
+
twenty-nine tools:
|
|
122
137
|
|
|
123
138
|
- `candle_launch_token`, `candle_get_market`, and `candle_get_feed` hit endpoints that use the
|
|
124
139
|
structured envelope `{ success: false, error: { code, message, ... } }`. Branch on `error.code`.
|
|
125
|
-
- `candle_report_activity` relays
|
|
140
|
+
- `candle_report_activity` relays the activity endpoint's own plain error shape
|
|
126
141
|
verbatim: `{ error: true, payload: string }`.
|
|
127
|
-
- `candle_get_agent_profile` relays
|
|
142
|
+
- `candle_get_agent_profile` relays the users endpoint's own plain error shape
|
|
128
143
|
verbatim: `{ error: string }`.
|
|
129
144
|
- `candle_trade` and `candle_launch_and_seed` wrap the underlying REST body instead of relaying it
|
|
130
145
|
bare, in one of two shapes depending on how far the call got:
|
|
@@ -153,8 +168,9 @@ twenty tools:
|
|
|
153
168
|
`candle_get_market` to fetch it separately.
|
|
154
169
|
- Either way, both tools echo their idempotency id (`clientTradeId` / `clientLaunchId`) at the
|
|
155
170
|
top level, so a caller can always find it to retry safely: retrying with the SAME id is a safe
|
|
156
|
-
replay, a new id is a second trade or launch. See
|
|
157
|
-
|
|
171
|
+
replay, a new id is a second trade or launch. See
|
|
172
|
+
[Candle MCP server](https://docs.candle.tv/developers/mcp-server) for the full idempotent-retry
|
|
173
|
+
rule.
|
|
158
174
|
|
|
159
175
|
## MCP client config
|
|
160
176
|
|
|
@@ -209,3 +225,33 @@ this on machines that have node and may not have bun.
|
|
|
209
225
|
calls with multi-field zod input shapes coexist in one file, which this package's tools
|
|
210
226
|
always will. `1.22.0` predates that rewrite and type-checks cleanly with the exact same tool
|
|
211
227
|
code. Re-check this pin when bumping the SDK.
|
|
228
|
+
|
|
229
|
+
### Hyperliquid per-key PnL
|
|
230
|
+
|
|
231
|
+
`candle pnl --profile <name>` / SDK `getProfilePnl(keyPrefix)` / MCP `candle_get_profile_pnl`
|
|
232
|
+
read the existing `GET /api/v1/agent/keys/{prefix}/pnl`. The answer adds an optional
|
|
233
|
+
`hyperliquid` section, and the CLI prints it under **Hyperliquid**. The existing read
|
|
234
|
+
authentication applies; on an older API the section is simply absent. No additional signing, deposit or setup is needed for this read.
|
|
235
|
+
|
|
236
|
+
The section reports main-exchange perp `realizedGrossUsd` (venue `closedPnl`), signed
|
|
237
|
+
`fundingUsd` (received positive, paid negative), `feesUsd` (venue fees including builder fees;
|
|
238
|
+
rebates are negative), and `realizedNetUsd = realizedGrossUsd + fundingUsd - feesUsd`.
|
|
239
|
+
Builder fees are already included in the venue fee and are not subtracted again. These figures
|
|
240
|
+
stay separate from spot and LP totals and exclude unrealized perps, deposits and withdrawals.
|
|
241
|
+
|
|
242
|
+
Coverage is **currently bound EVM TEE wallets since the current TEE binding**,
|
|
243
|
+
shown in `byWallet` with `startTime` in epoch milliseconds. That start is the latest rebind
|
|
244
|
+
onto this key, or the wallet's creation time when it was bound then and never rebound. A
|
|
245
|
+
rebound wallet does not bring its previous key's history. A wallet-set row is not required,
|
|
246
|
+
and an older one cannot move the start earlier than the binding. Revoked and previous
|
|
247
|
+
bindings, spot and HIP-3 fills are excluded. This is a binding-period read, not lifetime or
|
|
248
|
+
order-level attribution.
|
|
249
|
+
|
|
250
|
+
Reads use the venue client's two-second cache. `userFills` is capped at 2,000 recent rows;
|
|
251
|
+
`userFunding` at 500 rows from `startTime`, and this response covers at most 20 bound
|
|
252
|
+
wallets. `truncated` flags any reached history cap or remaining wallet page; `byWallet` names
|
|
253
|
+
`fillsTruncated` and `fundingTruncated`. Funding and fills can cover different time spans when
|
|
254
|
+
capped: a partial net must not be quoted as a lifetime figure. On upstream, wallet-discovery or
|
|
255
|
+
malformed-data failure the section is `{ read: false, reason }`, without amounts; spot PnL still
|
|
256
|
+
answers. An empty successful read is `{ read: true, ... }` with zero amounts. `--json` preserves
|
|
257
|
+
the section and its coverage fields. Agent boards are outside this slice.
|