@candledottv/mcp 0.10.8 → 0.10.10
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 +2 -2
- package/dist/index.js +21 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -98,8 +98,8 @@ tools, getting a key, funding the embedded wallet, and idempotent retries, see
|
|
|
98
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`) |
|
|
99
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` |
|
|
100
100
|
| `candle_swap` | Swap between base assets | `POST /api/v1/agent/swap` | `CANDLE_AGENT_API_KEY` (`swap:write`) |
|
|
101
|
-
| `candle_transfer` | Transfer an asset | `POST /api/v1/agent/transfer` | `CANDLE_AGENT_API_KEY
|
|
102
|
-
| `candle_sweep` | Sweep a wallet to one destination | One `POST /api/v1/agent/transfer` per asset, `amountRaw: "max"` | `CANDLE_AGENT_API_KEY
|
|
101
|
+
| `candle_transfer` | Transfer an asset | `POST /api/v1/agent/transfer` | `CANDLE_AGENT_API_KEY`, Withdraw (`transfer:write`) |
|
|
102
|
+
| `candle_sweep` | Sweep a wallet to one destination | One `POST /api/v1/agent/transfer` per asset, `amountRaw: "max"` | `CANDLE_AGENT_API_KEY`, Withdraw (`transfer:write`) |
|
|
103
103
|
| `candle_resolve_token` | Turn a bare mint or contract address into Candle's market for it | `GET /api/v1/markets/:chain/:mint` | none |
|
|
104
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` |
|
|
105
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` |
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
6
|
|
|
7
|
+
// src/market-disclosure.ts
|
|
8
|
+
var EXTERNAL_MARKET_DISCLOSURE = "For external tokens (external: true), buysOpen, sellsOpen, quoteMint, feeBps, venue, " + "graduationVenue and poolAddress are compatibility placeholders, not measured facts about " + "trading availability, pool pairing, fees or pool venue; trade.routable is stored eligibility " + "and does not verify those fields.";
|
|
9
|
+
|
|
7
10
|
// src/tools.ts
|
|
8
11
|
import { z as z2 } from "zod";
|
|
9
12
|
|
|
@@ -106,7 +109,7 @@ function percentOfBalance(balanceRaw, percent) {
|
|
|
106
109
|
import { randomUUID } from "node:crypto";
|
|
107
110
|
|
|
108
111
|
// src/version.ts
|
|
109
|
-
var SERVER_VERSION = "0.10.
|
|
112
|
+
var SERVER_VERSION = "0.10.10";
|
|
110
113
|
|
|
111
114
|
// src/update-notice.ts
|
|
112
115
|
var PLAIN_VERSION = /^\d+\.\d+\.\d+$/;
|
|
@@ -1532,7 +1535,7 @@ function buildRequest(name, args, cfg) {
|
|
|
1532
1535
|
...where ? { where } : {},
|
|
1533
1536
|
...sort ? { sort } : {},
|
|
1534
1537
|
...fields ? { fields } : {},
|
|
1535
|
-
...limit ? { limit } : {}
|
|
1538
|
+
...limit !== undefined && limit !== "" ? { limit: String(limit) } : {}
|
|
1536
1539
|
});
|
|
1537
1540
|
return {
|
|
1538
1541
|
url: `${base2}/api/v1/markets/feed?${query.toString()}`,
|
|
@@ -1676,13 +1679,22 @@ var tokenForensicsShape = {
|
|
|
1676
1679
|
chain: z2.string().describe('"solana" or "hood"'),
|
|
1677
1680
|
mint: z2.string().describe("Token mint (solana) or contract address (hood)")
|
|
1678
1681
|
};
|
|
1682
|
+
var FEED_LIMIT_MESSAGE = "limit must be a whole number from 1 to 200";
|
|
1683
|
+
var feedLimit = z2.preprocess((value) => {
|
|
1684
|
+
if (typeof value !== "string")
|
|
1685
|
+
return value;
|
|
1686
|
+
const trimmed = value.trim();
|
|
1687
|
+
if (trimmed === "")
|
|
1688
|
+
return;
|
|
1689
|
+
return /^[0-9]+$/.test(trimmed) ? Number(trimmed) : value;
|
|
1690
|
+
}, z2.number({ invalid_type_error: FEED_LIMIT_MESSAGE }).int(FEED_LIMIT_MESSAGE).min(1, FEED_LIMIT_MESSAGE).max(200, FEED_LIMIT_MESSAGE).optional().describe("Max rows to return, an integer from 1 to 200."));
|
|
1679
1691
|
var getFeedShape = {
|
|
1680
|
-
bucket: z2.enum(["new", "graduated", "onfire", "bluechip"]),
|
|
1692
|
+
bucket: z2.enum(["new", "graduated", "onfire", "bluechip", "finalstretch"]).describe("finalstretch: pump.fun tokens at 50% or more of their bonding curve, most complete first; no delta, read the whole list. Where it is not switched on it is refused as an unknown bucket: use another bucket. bluechip is deprecated and will be removed."),
|
|
1681
1693
|
chain: z2.string().optional().describe("Optional chain filter"),
|
|
1682
1694
|
where: z2.string().optional().describe('JSON filter, e.g. {"marketCap":{"lt":150000},"liquidityUsd":{"gte":25000},"mintAuthorityDisabled":{"eq":true}}. ' + "Comparators: eq, ne, lt, lte, gt, gte, present. An ABSENT field satisfies none of them except " + "present:false, so a filter for mintAuthorityDisabled eq true returns only tokens that actually say " + "true, never ones where the flag is simply missing. Use present:false to find the tokens with no data."),
|
|
1683
1695
|
sort: z2.string().optional().describe('Sort as "field" or "field:asc" / "field:desc". A bare field means desc.'),
|
|
1684
1696
|
fields: z2.string().optional().describe("Comma-separated fields to return, e.g. symbol,marketCap,liquidityUsd. chain, address and symbol always " + "ride along. Cuts a 135KB response to a couple of KB."),
|
|
1685
|
-
limit:
|
|
1697
|
+
limit: feedLimit
|
|
1686
1698
|
};
|
|
1687
1699
|
var reportActivityShape = {
|
|
1688
1700
|
chain: z2.string().describe('"solana" or "hood"'),
|
|
@@ -1774,7 +1786,7 @@ function registerToolSubset(server, options) {
|
|
|
1774
1786
|
}, async (args) => callAndRelay("candle_launch_token", args, getConfig(), doFetch));
|
|
1775
1787
|
register("candle_get_market", {
|
|
1776
1788
|
title: "Get market state",
|
|
1777
|
-
description: "Read Candle and indexed external markets, including indexed-but-not-routable tokens. No key needed. " + "Read candleLaunched, launchpad, venue and trade.routable; jupiterOk and discovery flags are distinct. " + "Routability is stored eligibility, not a quote or permission. General quotes use POST /api/v1/trade/agent/quote. " + "Curve quotes and lifecycle describe Candle launches. MARKET_NOT_FOUND is a legacy code: read " + "error.routing.reason, error.discovery and sibling error.retryable. A curve-only 404 does not mean untradeable.",
|
|
1789
|
+
description: "Read Candle and indexed external markets, including indexed-but-not-routable tokens. No key needed. " + EXTERNAL_MARKET_DISCLOSURE + " " + "Read candleLaunched, launchpad, venue and trade.routable; jupiterOk and discovery flags are distinct. " + "Routability is stored eligibility, not a quote or permission. General quotes use POST /api/v1/trade/agent/quote. " + "Curve quotes and lifecycle describe Candle launches. MARKET_NOT_FOUND is a legacy code: read " + "error.routing.reason, error.discovery and sibling error.retryable. A curve-only 404 does not mean untradeable.",
|
|
1778
1790
|
inputSchema: getMarketShape
|
|
1779
1791
|
}, async (args) => callAndRelay("candle_get_market", args, getConfig(), doFetch));
|
|
1780
1792
|
register("candle_token_forensics", {
|
|
@@ -1786,7 +1798,7 @@ MARKET_NOT_FOUND means Candle has no market for that token and this could not ru
|
|
|
1786
1798
|
}, async (args) => callAndRelay("candle_token_forensics", args, getConfig(), doFetch));
|
|
1787
1799
|
register("candle_get_feed", {
|
|
1788
1800
|
title: "Get a token feed",
|
|
1789
|
-
description: "Read one of the trade page's public feeds: new, graduated, onfire, or bluechip. Reads " + `only; moves nothing. No key needed. Start here when nobody has named a token.
|
|
1801
|
+
description: "Read one of the trade page's public feeds: new, graduated, onfire, or finalstretch " + "(bluechip still answers, is deprecated, and will be removed; where finalstretch is not " + "switched on it is refused as an unknown bucket, so use another bucket). Reads " + `only; moves nothing. No key needed. Start here when nobody has named a token.
|
|
1790
1802
|
|
|
1791
1803
|
` + "This indexes the WIDER market, not just Candle's own launches. Rows carry launchpad and " + "discovery flags (jupiterOk, externalTradeable, paperDiscoveryOk, organic0LiveOk). " + "candle_get_market resolves Jupiter-indexed rows; do not hard-skip organicScore=0 on live " + "when organic0LiveOk is true. liquidityDrawdownBps is a signal only — nothing here blocks " + `resolve or trade on drain; filter with where if you want to avoid draining pools.
|
|
1792
1804
|
|
|
@@ -1866,7 +1878,7 @@ MARKET_NOT_FOUND means Candle has no market for that token and this could not ru
|
|
|
1866
1878
|
}, async () => callAndRelay("candle_get_portfolio", {}, getConfig(), doFetch));
|
|
1867
1879
|
register("candle_resolve_token", {
|
|
1868
1880
|
title: "Resolve a contract address to a token",
|
|
1869
|
-
description: "Turn a bare contract address or mint into Candle's market for it: chain, symbol, " + "decimals, quote asset, and whether Candle can trade it. Start here when a human gives " + "you an address and nothing else. The chain is read off the address's own shape and is " + "not guessed, so it does not need to be supplied. Reads only; moves nothing. A 404 means " + "Candle has no market for that address, which is an answer, not a failure to retry.",
|
|
1881
|
+
description: "Turn a bare contract address or mint into Candle's market for it: chain, symbol, " + "decimals, quote asset, and whether Candle can trade it. Start here when a human gives " + "you an address and nothing else. The chain is read off the address's own shape and is " + "not guessed, so it does not need to be supplied. Reads only; moves nothing. A 404 means " + "Candle has no market for that address, which is an answer, not a failure to retry. " + EXTERNAL_MARKET_DISCLOSURE,
|
|
1870
1882
|
inputSchema: resolveTokenShape
|
|
1871
1883
|
}, async (args) => {
|
|
1872
1884
|
const result = await resolveToken(args, getConfig(), doFetch);
|
|
@@ -1996,7 +2008,7 @@ var INSTRUCTIONS = `Candle is a trading and token-launch rail for agents. You ho
|
|
|
1996
2008
|
|
|
1997
2009
|
START HERE — six tools need NO credential. Call these first to confirm the server is wired before asking anyone for anything:
|
|
1998
2010
|
candle_get_market price, market cap, volume, curve state for one token
|
|
1999
|
-
candle_get_feed the roster: hot streak, new pairs, graduated, blue chip
|
|
2011
|
+
candle_get_feed the roster: hot streak, new pairs, graduated, final stretch, blue chip (final stretch is refused where it is not switched on; use another bucket)
|
|
2000
2012
|
candle_resolve_token a ticker or partial name -> mint address + chain
|
|
2001
2013
|
candle_token_forensics call this before quoting or buying. Returns the on-chain developer (never a launchpad shared authority; deployer.attribution names the launchpad or issuer when no developer is on chain), their went-to-zero rate and last coins, who bought in the deploy window (strangers in the same slot are the bundle signal), same-funder insider share, same-funder cluster, and safety.summary with six sourced flags. Refuse an unprompted buy when flagged; incomplete or unknown is not clearance. launch.deployerLaunches is an inclusive informational count, never a warning
|
|
2002
2014
|
candle_get_agent_profile your own tier, caps and verified activity
|
|
@@ -2011,6 +2023,7 @@ only when organic0LiveOk is false.
|
|
|
2011
2023
|
candle_get_market and candle_resolve_token answer for same-chain indexed external mints even
|
|
2012
2024
|
when trade.routable is false. Read candleLaunched, launchpad, venue and trade; jupiterOk and
|
|
2013
2025
|
paperDiscoveryOk are separate signals. Identity-only Solana reads have route_unverified.
|
|
2026
|
+
${EXTERNAL_MARKET_DISCLOSURE}
|
|
2014
2027
|
General quotes use POST /api/v1/trade/agent/quote; curve quotes/lifecycle describe Candle launches.
|
|
2015
2028
|
Stored eligibility is not a successful quote or permission. MARKET_NOT_FOUND remains a legacy
|
|
2016
2029
|
code: read error.routing.reason, error.discovery and sibling error.retryable. A curve-only
|