@candledottv/mcp 0.10.28 → 0.10.29
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 +4 -3
- package/dist/index.js +39 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @candledottv/mcp
|
|
2
2
|
|
|
3
3
|
An MCP (Model Context Protocol) server for the Candle agent rail. The current source exposes Candle's REST API as
|
|
4
|
-
eighty-
|
|
4
|
+
eighty-three tools over stdio, plus four Hyperliquid market reads (eighty-seven in all), 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, read one token's signals and tracked-wallet trades and its card data, report on-chain activity,
|
|
7
7
|
check an agent profile, and backtest a strategy in hacc's strategy lab without hand-rolling HTTP calls. The five
|
|
@@ -35,7 +35,7 @@ Environment below -- or skip env editing entirely: install the Candle CLI
|
|
|
35
35
|
environment.
|
|
36
36
|
|
|
37
37
|
`CANDLE_MCP_TOOLS` (optional) is a comma-separated allowlist of tool names; only those register.
|
|
38
|
-
Unset means all eighty-
|
|
38
|
+
Unset means all eighty-three. An unknown name fails startup with the valid names in the message, rather
|
|
39
39
|
than silently registering the wrong surface. `candle mcp --read-only` / `--tools` set this for
|
|
40
40
|
you.
|
|
41
41
|
|
|
@@ -163,6 +163,7 @@ tools, getting a key, funding the embedded wallet, and idempotent retries, see
|
|
|
163
163
|
| `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` |
|
|
164
164
|
| `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` |
|
|
165
165
|
| `candle_get_fees` | The creator fees the account's launched tokens can pay: raw amounts from chain reads, and the reason a token cannot be claimed | `GET /api/v1/agent/fees` | `CANDLE_AGENT_API_KEY` (`account:read`) |
|
|
166
|
+
| `candle_atomic_launch_dry_run` | Check a Solana launch with first buys and price each buy on the curve it would deploy; builds, reserves and writes nothing | `POST /api/v1/launch/atomic/dry-run` | `CANDLE_AGENT_API_KEY` (`launch:write`, `swap:write`, Pro or Max) |
|
|
166
167
|
| `candle_claim_fees` | Collect one token's creator fees to the wallet fixed at launch (no destination argument); `dryRun` sends nothing | `POST /api/v1/agent/fees/:mint/claim` | `CANDLE_AGENT_API_KEY` (`launch:write`) |
|
|
167
168
|
| `candle_get_staking` | Read CNDL/sCNDL, withdrawals, rewards, pool wait and wallet eligibility notes | `GET /api/v1/agent/staking` |
|
|
168
169
|
| `candle_stake` | Stake raw CNDL; stable clientStakeId, dryRun first | `POST /api/v1/agent/staking/stake/build` |
|
|
@@ -239,7 +240,7 @@ explicitly. Assets with nothing spendable report `empty`; a failed asset never s
|
|
|
239
240
|
## Errors
|
|
240
241
|
|
|
241
242
|
This package never reinterprets an error body, and that body is not one uniform shape across all
|
|
242
|
-
eighty-
|
|
243
|
+
eighty-three tools:
|
|
243
244
|
|
|
244
245
|
- `candle_token_events`, called with `kind`, is the one narrowing of a SUCCESS body, never an
|
|
245
246
|
error one: the relayed `events` are filtered to that kind and the body gains `filteredByKind`.
|
package/dist/index.js
CHANGED
|
@@ -189,7 +189,7 @@ function readClusterResult(value, mint) {
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
// src/version.ts
|
|
192
|
-
var SERVER_VERSION = "0.10.
|
|
192
|
+
var SERVER_VERSION = "0.10.29";
|
|
193
193
|
|
|
194
194
|
// src/update-notice.ts
|
|
195
195
|
var PLAIN_VERSION = /^\d+\.\d+\.\d+$/;
|
|
@@ -1445,7 +1445,7 @@ var LAUNCH_DEFINITION = {
|
|
|
1445
1445
|
{
|
|
1446
1446
|
key: "feeWallet",
|
|
1447
1447
|
type: "string",
|
|
1448
|
-
help: "Solana only: the wallet this launch's curve and pool fees earn to, an on-curve wallet or a Squads v4 vault; defaults to the account wallet.",
|
|
1448
|
+
help: "Solana only: the wallet this launch's curve and pool fees earn to, an on-curve wallet or a Squads v4 vault; defaults to the wallet that launches the token (the account wallet on a server without LAUNCH_FEE_WALLET_FROM_LAUNCHER, except an embedded launch).",
|
|
1449
1449
|
chains: [
|
|
1450
1450
|
"solana"
|
|
1451
1451
|
],
|
|
@@ -6338,6 +6338,7 @@ var TOOL_NAMES = [
|
|
|
6338
6338
|
"candle_get_plans",
|
|
6339
6339
|
"candle_trade",
|
|
6340
6340
|
"candle_launch_and_seed",
|
|
6341
|
+
"candle_atomic_launch_dry_run",
|
|
6341
6342
|
"candle_swap",
|
|
6342
6343
|
"candle_transfer",
|
|
6343
6344
|
"candle_sweep",
|
|
@@ -6472,6 +6473,18 @@ function buildRequest(name, args, cfg) {
|
|
|
6472
6473
|
init: { method: "POST", headers: jsonHeaders(apiKey), body: JSON.stringify(body) }
|
|
6473
6474
|
};
|
|
6474
6475
|
}
|
|
6476
|
+
case "candle_atomic_launch_dry_run": {
|
|
6477
|
+
const apiKey = requireApiKey2(cfg);
|
|
6478
|
+
const { payer, chain: _chain, buyAmount: _buyAmount, ...rest } = args;
|
|
6479
|
+
return {
|
|
6480
|
+
url: `${base2}/api/v1/launch/atomic/dry-run`,
|
|
6481
|
+
init: {
|
|
6482
|
+
method: "POST",
|
|
6483
|
+
headers: jsonHeaders(apiKey),
|
|
6484
|
+
body: JSON.stringify({ ...rest, chain: "solana", payer: payer ?? { type: "main" } })
|
|
6485
|
+
}
|
|
6486
|
+
};
|
|
6487
|
+
}
|
|
6475
6488
|
case "candle_get_market": {
|
|
6476
6489
|
const { chain, mint } = args;
|
|
6477
6490
|
return {
|
|
@@ -6911,6 +6924,22 @@ var getFeesShape = {
|
|
|
6911
6924
|
cursor: z9.string().optional().describe("The previous page's continueCursor, verbatim"),
|
|
6912
6925
|
limit: z9.number().optional().describe("Tokens per page, 1 to 50 (default 20). Each one costs chain reads")
|
|
6913
6926
|
};
|
|
6927
|
+
var atomicPayerShape = z9.union([
|
|
6928
|
+
z9.object({ type: z9.literal("main") }),
|
|
6929
|
+
z9.object({ type: z9.literal("linked"), linkedWalletId: z9.string().min(1) })
|
|
6930
|
+
]);
|
|
6931
|
+
var atomicLaunchDryRunShape = (() => {
|
|
6932
|
+
const { buyAmount: _buyAmount, chain: _chain, ...launch } = launchTokenShape;
|
|
6933
|
+
return {
|
|
6934
|
+
...launch,
|
|
6935
|
+
clientLaunchId: z9.string().optional().describe("Not used by a dry run; send the id you will launch with"),
|
|
6936
|
+
payer: atomicPayerShape.optional().describe("Who pays for the launch: {type:'main'} (default) or {type:'linked', linkedWalletId}"),
|
|
6937
|
+
firstBuys: z9.array(z9.object({
|
|
6938
|
+
payer: atomicPayerShape,
|
|
6939
|
+
amountRaw: z9.string().regex(/^[1-9][0-9]*$/).describe("Quote-asset raw units")
|
|
6940
|
+
})).min(1).max(4).describe("One to four first buys, each priced on the curve this launch would deploy")
|
|
6941
|
+
};
|
|
6942
|
+
})();
|
|
6914
6943
|
var claimFeesShape = {
|
|
6915
6944
|
mint: z9.string().describe("The launched token: a Solana mint or a Hood token address, as candle_get_fees lists it"),
|
|
6916
6945
|
dryRun: z9.boolean().optional().describe("Check and read only. Sends nothing and writes nothing. Use it first to see what would be claimed")
|
|
@@ -7303,12 +7332,12 @@ MARKET_NOT_FOUND means Candle has no market for that token and this could not ru
|
|
|
7303
7332
|
}, async (args) => callAndRelay("candle_claim_staking_reward", args, getConfig(), doFetch));
|
|
7304
7333
|
register("candle_get_fees", {
|
|
7305
7334
|
title: "Read the creator fees this account's tokens can pay",
|
|
7306
|
-
description: "The tokens launched by the account's own wallets, with what each could pay now in creator fees " + "(raw units from direct chain reads) and `
|
|
7335
|
+
description: "The tokens launched by the account's own wallets, with what each could pay now in creator fees " + "(raw units from direct chain reads) and a `reason` saying who can claim: `claimable_by_key` on a " + "claimable Solana row, and otherwise why this key cannot (including `claimable_via_web_session` " + "and `fee_wallet_designated`, which name whose authority collects). Reads only; " + "moves nothing. It returns no earned or paid-out totals. An unreadable token is marked, never " + "shown as zero. Paged: pass `continueCursor` back as `cursor`.",
|
|
7307
7336
|
inputSchema: getFeesShape
|
|
7308
7337
|
}, async (args) => callAndRelay("candle_get_fees", args, getConfig(), doFetch));
|
|
7309
7338
|
register("candle_claim_fees", {
|
|
7310
7339
|
title: "Claim a token's creator fees",
|
|
7311
|
-
description: "Collect one token's creator fees and pay them to the wallet fixed at launch. There is no destination " + "argument and the tool cannot send funds anywhere else. Candle signs with the embedded wallet, which " + "pays the network fee. Needs launch:write. " + "Call it with dryRun: true first; a real claim moves real funds into the recipient wallet, which may be " + "the wallet this agent trades from. Not idempotent by id: if the result is lost, read candle_get_fees " + "before claiming again.",
|
|
7340
|
+
description: "Collect one token's creator fees and pay them to the wallet fixed at launch. There is no destination " + "argument and the tool cannot send funds anywhere else. Candle signs with the embedded wallet, which " + "pays the network fee. A fee recipient that is a TEE wallet is refused here: claim it with the candle CLI " + "(`candle fees claim`). The dry run reports the same refusal (`claimable: false`, `reason: " + "wallet_not_signable`) and counts only what this tool could claim. Needs launch:write. " + "Call it with dryRun: true first; a real claim moves real funds into the recipient wallet, which may be " + "the wallet this agent trades from. Not idempotent by id: if the result is lost, read candle_get_fees " + "before claiming again.",
|
|
7312
7341
|
inputSchema: claimFeesShape
|
|
7313
7342
|
}, async (args) => callAndRelay("candle_claim_fees", args, getConfig(), doFetch));
|
|
7314
7343
|
register("candle_get_wallets", {
|
|
@@ -7416,6 +7445,12 @@ MARKET_NOT_FOUND means Candle has no market for that token and this could not ru
|
|
|
7416
7445
|
const result = await executeTrade(args, getConfig(), doFetch);
|
|
7417
7446
|
return { content: [{ type: "text", text: result.text }], ...result.isError ? { isError: true } : {} };
|
|
7418
7447
|
});
|
|
7448
|
+
register("candle_atomic_launch_dry_run", {
|
|
7449
|
+
title: "Dry-run an atomic Solana launch",
|
|
7450
|
+
description: "Check a Solana launch bundled with first buys and price each buy, without building anything. Runs the " + "same checks as the atomic build, in the same order (payers, Believer check, fee and spend limits, the " + "key's transaction cap), then returns the launch preview (curveTerms) and one fill per first buy: the " + "tokens it would receive and the floor the build would sign it at. Reads only; moves nothing, reserves " + "nothing, and the clientLaunchId stays unused. It does not check balances, the daily cap, or the " + "transaction's size, so the real launch can still refuse. Needs launch:write, swap:write and Pro or Max.",
|
|
7451
|
+
inputSchema: atomicLaunchDryRunShape,
|
|
7452
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }
|
|
7453
|
+
}, async (args) => callAndRelay("candle_atomic_launch_dry_run", args, getConfig(), doFetch));
|
|
7419
7454
|
register("candle_launch_and_seed", {
|
|
7420
7455
|
title: "Launch a token and seed it",
|
|
7421
7456
|
description: "Launch a new token from the account's embedded wallet, with an optional dev-buy seed, then " + "return the fresh market state and token links in one result. On solana a seed makes this " + (options.headlessSeed === true ? "the seed is a separate first-buy transaction in the same Jito bundle as the launch, so " + "both land or neither does. That works on every plan, Free included, and needs no " + "swap:write. On hood the seed is " : "the atomic launch: the launch and the seed are two transactions Candle signs and sends as " + "one Jito bundle, so both land or neither does. That needs Pro or Max (TIER_REQUIRED " + "otherwise) and swap:write on the key, and the result carries bundleId. On hood the seed is ") + "a best-effort follow-up. A launch with no seed works on every plan, Free included. MOVES " + "REAL FUNDS unless dryRun; dry-run first, which spends nothing. Seeds above the platform " + "dev-buy ceiling are rejected (DEV_BUY_TOO_HIGH): at most 0.5 SOL / 500 USDC / 2,000,000 " + "CNDL, or on an exp- curve 10% of the threshold when that is lower; the server holds the " + "creator's own seed to the effective ceiling, so launch with the largest devBuy it allows " + "and top up with candle_trade. " + LAUNCH_SHARED_SENTENCES + (imageDir ? IMAGE_PATH_DISCLOSURE : ""),
|