@ldgr/mcp 0.1.3 → 0.1.4
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 +22 -1
- package/dist/cli.js +19 -4
- package/dist/index.js +18 -3
- package/dist/requests.d.ts +1 -1
- package/dist/stdio.js +18 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ A remote MCP connection cannot install software, access local files, unlock a wa
|
|
|
13
13
|
Node.js 20.19 or newer is required. Install the package, then create or import a wallet in your own terminal:
|
|
14
14
|
|
|
15
15
|
```sh
|
|
16
|
-
npm install --global @ldgr/mcp@0.1.
|
|
16
|
+
npm install --global @ldgr/mcp@0.1.4
|
|
17
17
|
ldgr-mcp wallet create --testnet
|
|
18
18
|
# Or: ldgr-mcp wallet import --testnet
|
|
19
19
|
ldgr-mcp wallet list
|
|
@@ -68,6 +68,7 @@ Restart the MCP process after upgrading; a running process keeps its loaded SDK.
|
|
|
68
68
|
| `prepare_transfer` | Unsigned transfer request |
|
|
69
69
|
| `prepare_token_creation` | Unsigned fixed/mintable token creation request |
|
|
70
70
|
| `prepare_escrow` | Unsigned escrow funding request |
|
|
71
|
+
| `prepare_swap` | Unsigned exact-input swap with an explicit positive minimum received |
|
|
71
72
|
| `wallet_setup_instructions` | Exact local installation and setup commands |
|
|
72
73
|
| `wallet_info` | Public selected-wallet metadata, local stdio only |
|
|
73
74
|
|
|
@@ -104,6 +105,26 @@ npx --yes --package @ldgr/mcp@latest ldgr-mcp approve <request-file>
|
|
|
104
105
|
|
|
105
106
|
The CLI validates the request and selected network, resolves fresh asset precision, checks the ledger's current fees and nonces, and presents the transaction for explicit local approval. Do not run approval unattended. Prepared requests may become invalid as balances, fees, configuration, or deadlines change. Reconcile an uncertain submission before trying again.
|
|
106
107
|
|
|
108
|
+
## Swaps
|
|
109
|
+
|
|
110
|
+
MCP 0.1.4 adds `prepare_swap`; approving these requests requires CLI 0.5.2 or
|
|
111
|
+
newer. First use `get_swap_quote` for a non-binding quote. Then prepare an intent
|
|
112
|
+
with explicit `network`, `assetIn`, `assetOut`, `amountIn`, and `amountOutMin`.
|
|
113
|
+
Both amounts are positive decimal strings in their respective asset's display
|
|
114
|
+
units. `maxHops` is optional, accepts 1, 2, or 3, and defaults to 3. Native aliases
|
|
115
|
+
`t0`/`t1` resolve to `dng` for the selected network. Identical assets and zero
|
|
116
|
+
minimum output are rejected.
|
|
117
|
+
|
|
118
|
+
Preparation does not select a route or execute a swap. During `approve`, the
|
|
119
|
+
CLI fetches a fresh route, checks the input balance and native fee balance, and
|
|
120
|
+
shows the route, quote, exact input and minimum received. Output returns to the
|
|
121
|
+
selected wallet. The reviewed route and minimum are signed unchanged; the CLI
|
|
122
|
+
never lowers the minimum to make a quote executable. Pool fees are included in
|
|
123
|
+
the quote, while one additional native network fee is charged. Route swaps use
|
|
124
|
+
the `dng` nonce even when swapping between two tokens. The portable request's
|
|
125
|
+
expiry governs local approval; the existing protocol timestamp rules govern
|
|
126
|
+
signed submission validity.
|
|
127
|
+
|
|
107
128
|
## Embedding
|
|
108
129
|
|
|
109
130
|
```ts
|
package/dist/cli.js
CHANGED
|
@@ -249,7 +249,7 @@ class AssetMismatchError extends Error {
|
|
|
249
249
|
class WalletNetworkMismatchError extends Error {
|
|
250
250
|
}
|
|
251
251
|
function createLdgrMcpServer(options = {}) {
|
|
252
|
-
const server = new McpServer({ name: "ldgr", version: "0.1.
|
|
252
|
+
const server = new McpServer({ name: "ldgr", version: "0.1.4" }, { instructions: INSTRUCTIONS });
|
|
253
253
|
const request = readTransport(options.fetch);
|
|
254
254
|
const now = options.now ?? Date.now;
|
|
255
255
|
const envelope = (network, source, data) => ({ network, source, data });
|
|
@@ -349,12 +349,27 @@ function createLdgrMcpServer(options = {}) {
|
|
|
349
349
|
const a = exactAsset(args.assetA, args.network), b = exactAsset(args.assetB, args.network), client = await checkedClient(args.network, request);
|
|
350
350
|
return envelope(args.network, "ledger", await client.amm.getPoolByPair(a, b));
|
|
351
351
|
});
|
|
352
|
-
tool("get_swap_quote", "Read a non-binding swap quote for explicit input/output assets.
|
|
352
|
+
tool("get_swap_quote", "Read a non-binding swap quote for explicit input/output assets. Use prepare_swap with an explicit positive minimum received to prepare an unsigned intent; only human CLI approval can execute it.", { network: networkSchema, assetIn: assetSchema, assetOut: assetSchema, amountIn: positiveDecimalSchema }, async (args) => {
|
|
353
353
|
const assetIn = exactAsset(args.assetIn, args.network), assetOut = exactAsset(args.assetOut, args.network);
|
|
354
354
|
checkNativeAmount(assetIn, args.amountIn, args.network);
|
|
355
355
|
const client = await checkedClient(args.network, request);
|
|
356
356
|
return envelope(args.network, "ledger", await client.amm.quoteRoute(assetIn, assetOut, args.amountIn, 3));
|
|
357
357
|
});
|
|
358
|
+
tool("prepare_swap", "Prepare an unsigned exact-input swap for human CLI approval. Specify both assets, amountIn and a positive amountOutMin in decimal display units. The CLI fetches a fresh route of up to maxHops pools and shows it before signing; it never lowers the minimum. Output goes to the selected wallet. Preparation does not quote, unlock, sign or submit.", {
|
|
359
|
+
network: networkSchema,
|
|
360
|
+
assetIn: assetSchema,
|
|
361
|
+
assetOut: assetSchema,
|
|
362
|
+
amountIn: positiveDecimalSchema,
|
|
363
|
+
amountOutMin: positiveDecimalSchema,
|
|
364
|
+
maxHops: z2.number().int().min(1).max(3).default(3)
|
|
365
|
+
}, async (args) => {
|
|
366
|
+
const assetIn = exactAsset(args.assetIn, args.network), assetOut = exactAsset(args.assetOut, args.network);
|
|
367
|
+
if (assetIn === assetOut)
|
|
368
|
+
throw new Error("Swap assets must differ");
|
|
369
|
+
checkNativeAmount(assetIn, args.amountIn, args.network);
|
|
370
|
+
checkNativeAmount(assetOut, args.amountOutMin, args.network);
|
|
371
|
+
return prepared(unsignedRequest(args.network, "swap", { assetIn, assetOut, amountIn: args.amountIn, amountOutMin: args.amountOutMin, maxHops: args.maxHops }, now()));
|
|
372
|
+
}, false);
|
|
358
373
|
tool("prepare_transfer", "Prepare an unsigned transfer for human review in the local CLI wallet. Does not unlock, sign or submit.", { network: networkSchema, to: addressSchema, asset: assetSchema, amount: positiveDecimalSchema, memo: referenceSchema.optional() }, async (args) => {
|
|
359
374
|
const to = addressForNetwork(args.to, args.network), asset = exactAsset(args.asset, args.network);
|
|
360
375
|
checkNativeAmount(asset, args.amount, args.network);
|
|
@@ -398,7 +413,7 @@ function createLdgrMcpServer(options = {}) {
|
|
|
398
413
|
}, false);
|
|
399
414
|
tool("wallet_setup_instructions", "Explain user-run CLI wallet installation, creation/import and MCP connection. This tool cannot install software or access local files.", { network: networkSchema }, async (args) => ({
|
|
400
415
|
network: args.network,
|
|
401
|
-
install: "npm install --global @ldgr/mcp@0.1.
|
|
416
|
+
install: "npm install --global @ldgr/mcp@0.1.4",
|
|
402
417
|
node: ">=20.19.0",
|
|
403
418
|
create: `ldgr-mcp wallet create${args.network === "testnet" ? " --testnet" : ""}`,
|
|
404
419
|
import: `ldgr-mcp wallet import${args.network === "testnet" ? " --testnet" : ""}`,
|
|
@@ -477,7 +492,7 @@ async function startLdgrMcpStdio(options = {}) {
|
|
|
477
492
|
}
|
|
478
493
|
|
|
479
494
|
// src/cli.ts
|
|
480
|
-
var HELP = `LDGR MCP 0.1.
|
|
495
|
+
var HELP = `LDGR MCP 0.1.4
|
|
481
496
|
|
|
482
497
|
ldgr-mcp Start local MCP over stdio
|
|
483
498
|
ldgr-mcp --wallet <path> Start MCP with a selected wallet store
|
package/dist/index.js
CHANGED
|
@@ -121,7 +121,7 @@ class AssetMismatchError extends Error {
|
|
|
121
121
|
class WalletNetworkMismatchError extends Error {
|
|
122
122
|
}
|
|
123
123
|
function createLdgrMcpServer(options = {}) {
|
|
124
|
-
const server = new McpServer({ name: "ldgr", version: "0.1.
|
|
124
|
+
const server = new McpServer({ name: "ldgr", version: "0.1.4" }, { instructions: INSTRUCTIONS });
|
|
125
125
|
const request = readTransport(options.fetch);
|
|
126
126
|
const now = options.now ?? Date.now;
|
|
127
127
|
const envelope = (network, source, data) => ({ network, source, data });
|
|
@@ -221,12 +221,27 @@ function createLdgrMcpServer(options = {}) {
|
|
|
221
221
|
const a = exactAsset(args.assetA, args.network), b = exactAsset(args.assetB, args.network), client = await checkedClient(args.network, request);
|
|
222
222
|
return envelope(args.network, "ledger", await client.amm.getPoolByPair(a, b));
|
|
223
223
|
});
|
|
224
|
-
tool("get_swap_quote", "Read a non-binding swap quote for explicit input/output assets.
|
|
224
|
+
tool("get_swap_quote", "Read a non-binding swap quote for explicit input/output assets. Use prepare_swap with an explicit positive minimum received to prepare an unsigned intent; only human CLI approval can execute it.", { network: networkSchema, assetIn: assetSchema, assetOut: assetSchema, amountIn: positiveDecimalSchema }, async (args) => {
|
|
225
225
|
const assetIn = exactAsset(args.assetIn, args.network), assetOut = exactAsset(args.assetOut, args.network);
|
|
226
226
|
checkNativeAmount(assetIn, args.amountIn, args.network);
|
|
227
227
|
const client = await checkedClient(args.network, request);
|
|
228
228
|
return envelope(args.network, "ledger", await client.amm.quoteRoute(assetIn, assetOut, args.amountIn, 3));
|
|
229
229
|
});
|
|
230
|
+
tool("prepare_swap", "Prepare an unsigned exact-input swap for human CLI approval. Specify both assets, amountIn and a positive amountOutMin in decimal display units. The CLI fetches a fresh route of up to maxHops pools and shows it before signing; it never lowers the minimum. Output goes to the selected wallet. Preparation does not quote, unlock, sign or submit.", {
|
|
231
|
+
network: networkSchema,
|
|
232
|
+
assetIn: assetSchema,
|
|
233
|
+
assetOut: assetSchema,
|
|
234
|
+
amountIn: positiveDecimalSchema,
|
|
235
|
+
amountOutMin: positiveDecimalSchema,
|
|
236
|
+
maxHops: z2.number().int().min(1).max(3).default(3)
|
|
237
|
+
}, async (args) => {
|
|
238
|
+
const assetIn = exactAsset(args.assetIn, args.network), assetOut = exactAsset(args.assetOut, args.network);
|
|
239
|
+
if (assetIn === assetOut)
|
|
240
|
+
throw new Error("Swap assets must differ");
|
|
241
|
+
checkNativeAmount(assetIn, args.amountIn, args.network);
|
|
242
|
+
checkNativeAmount(assetOut, args.amountOutMin, args.network);
|
|
243
|
+
return prepared(unsignedRequest(args.network, "swap", { assetIn, assetOut, amountIn: args.amountIn, amountOutMin: args.amountOutMin, maxHops: args.maxHops }, now()));
|
|
244
|
+
}, false);
|
|
230
245
|
tool("prepare_transfer", "Prepare an unsigned transfer for human review in the local CLI wallet. Does not unlock, sign or submit.", { network: networkSchema, to: addressSchema, asset: assetSchema, amount: positiveDecimalSchema, memo: referenceSchema.optional() }, async (args) => {
|
|
231
246
|
const to = addressForNetwork(args.to, args.network), asset = exactAsset(args.asset, args.network);
|
|
232
247
|
checkNativeAmount(asset, args.amount, args.network);
|
|
@@ -270,7 +285,7 @@ function createLdgrMcpServer(options = {}) {
|
|
|
270
285
|
}, false);
|
|
271
286
|
tool("wallet_setup_instructions", "Explain user-run CLI wallet installation, creation/import and MCP connection. This tool cannot install software or access local files.", { network: networkSchema }, async (args) => ({
|
|
272
287
|
network: args.network,
|
|
273
|
-
install: "npm install --global @ldgr/mcp@0.1.
|
|
288
|
+
install: "npm install --global @ldgr/mcp@0.1.4",
|
|
274
289
|
node: ">=20.19.0",
|
|
275
290
|
create: `ldgr-mcp wallet create${args.network === "testnet" ? " --testnet" : ""}`,
|
|
276
291
|
import: `ldgr-mcp wallet import${args.network === "testnet" ? " --testnet" : ""}`,
|
package/dist/requests.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type UnsignedMcpRequest = {
|
|
|
5
5
|
readonly requestId: string;
|
|
6
6
|
readonly network: McpNetwork;
|
|
7
7
|
readonly expiresAt: string;
|
|
8
|
-
readonly action: "transfer" | "create_token" | "open_escrow";
|
|
8
|
+
readonly action: "transfer" | "create_token" | "open_escrow" | "swap";
|
|
9
9
|
readonly params: Readonly<Record<string, string | number | undefined>>;
|
|
10
10
|
};
|
|
11
11
|
export declare const networkSchema: z.ZodEnum<{
|
package/dist/stdio.js
CHANGED
|
@@ -247,7 +247,7 @@ class AssetMismatchError extends Error {
|
|
|
247
247
|
class WalletNetworkMismatchError extends Error {
|
|
248
248
|
}
|
|
249
249
|
function createLdgrMcpServer(options = {}) {
|
|
250
|
-
const server = new McpServer({ name: "ldgr", version: "0.1.
|
|
250
|
+
const server = new McpServer({ name: "ldgr", version: "0.1.4" }, { instructions: INSTRUCTIONS });
|
|
251
251
|
const request = readTransport(options.fetch);
|
|
252
252
|
const now = options.now ?? Date.now;
|
|
253
253
|
const envelope = (network, source, data) => ({ network, source, data });
|
|
@@ -347,12 +347,27 @@ function createLdgrMcpServer(options = {}) {
|
|
|
347
347
|
const a = exactAsset(args.assetA, args.network), b = exactAsset(args.assetB, args.network), client = await checkedClient(args.network, request);
|
|
348
348
|
return envelope(args.network, "ledger", await client.amm.getPoolByPair(a, b));
|
|
349
349
|
});
|
|
350
|
-
tool("get_swap_quote", "Read a non-binding swap quote for explicit input/output assets.
|
|
350
|
+
tool("get_swap_quote", "Read a non-binding swap quote for explicit input/output assets. Use prepare_swap with an explicit positive minimum received to prepare an unsigned intent; only human CLI approval can execute it.", { network: networkSchema, assetIn: assetSchema, assetOut: assetSchema, amountIn: positiveDecimalSchema }, async (args) => {
|
|
351
351
|
const assetIn = exactAsset(args.assetIn, args.network), assetOut = exactAsset(args.assetOut, args.network);
|
|
352
352
|
checkNativeAmount(assetIn, args.amountIn, args.network);
|
|
353
353
|
const client = await checkedClient(args.network, request);
|
|
354
354
|
return envelope(args.network, "ledger", await client.amm.quoteRoute(assetIn, assetOut, args.amountIn, 3));
|
|
355
355
|
});
|
|
356
|
+
tool("prepare_swap", "Prepare an unsigned exact-input swap for human CLI approval. Specify both assets, amountIn and a positive amountOutMin in decimal display units. The CLI fetches a fresh route of up to maxHops pools and shows it before signing; it never lowers the minimum. Output goes to the selected wallet. Preparation does not quote, unlock, sign or submit.", {
|
|
357
|
+
network: networkSchema,
|
|
358
|
+
assetIn: assetSchema,
|
|
359
|
+
assetOut: assetSchema,
|
|
360
|
+
amountIn: positiveDecimalSchema,
|
|
361
|
+
amountOutMin: positiveDecimalSchema,
|
|
362
|
+
maxHops: z2.number().int().min(1).max(3).default(3)
|
|
363
|
+
}, async (args) => {
|
|
364
|
+
const assetIn = exactAsset(args.assetIn, args.network), assetOut = exactAsset(args.assetOut, args.network);
|
|
365
|
+
if (assetIn === assetOut)
|
|
366
|
+
throw new Error("Swap assets must differ");
|
|
367
|
+
checkNativeAmount(assetIn, args.amountIn, args.network);
|
|
368
|
+
checkNativeAmount(assetOut, args.amountOutMin, args.network);
|
|
369
|
+
return prepared(unsignedRequest(args.network, "swap", { assetIn, assetOut, amountIn: args.amountIn, amountOutMin: args.amountOutMin, maxHops: args.maxHops }, now()));
|
|
370
|
+
}, false);
|
|
356
371
|
tool("prepare_transfer", "Prepare an unsigned transfer for human review in the local CLI wallet. Does not unlock, sign or submit.", { network: networkSchema, to: addressSchema, asset: assetSchema, amount: positiveDecimalSchema, memo: referenceSchema.optional() }, async (args) => {
|
|
357
372
|
const to = addressForNetwork(args.to, args.network), asset = exactAsset(args.asset, args.network);
|
|
358
373
|
checkNativeAmount(asset, args.amount, args.network);
|
|
@@ -396,7 +411,7 @@ function createLdgrMcpServer(options = {}) {
|
|
|
396
411
|
}, false);
|
|
397
412
|
tool("wallet_setup_instructions", "Explain user-run CLI wallet installation, creation/import and MCP connection. This tool cannot install software or access local files.", { network: networkSchema }, async (args) => ({
|
|
398
413
|
network: args.network,
|
|
399
|
-
install: "npm install --global @ldgr/mcp@0.1.
|
|
414
|
+
install: "npm install --global @ldgr/mcp@0.1.4",
|
|
400
415
|
node: ">=20.19.0",
|
|
401
416
|
create: `ldgr-mcp wallet create${args.network === "testnet" ? " --testnet" : ""}`,
|
|
402
417
|
import: `ldgr-mcp wallet import${args.network === "testnet" ? " --testnet" : ""}`,
|