@elisym/mcp 0.15.2 → 0.15.3

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 CHANGED
@@ -24,7 +24,8 @@ npx @elisym/mcp install --agent <agent-name>
24
24
  # List detected MCP clients
25
25
  npx @elisym/mcp install --list
26
26
 
27
- # Refresh the version pin in installed clients (preserves agent + env)
27
+ # Installs pin to @latest, so npx pulls the newest build on each restart.
28
+ # Run update only to force a refresh (clears the npx cache; preserves agent + env).
28
29
  npx @elisym/mcp update
29
30
 
30
31
  # Remove from MCP clients
package/dist/index.js CHANGED
@@ -5,19 +5,19 @@ import { createIrohTransport, loadGlobalConfig, writeGlobalConfig } from '@elisy
5
5
  import { getBase58Encoder, getBase58Decoder, generateKeyPairSigner, createSolanaRpc, address, createSolanaRpcSubscriptions, sendAndConfirmTransactionFactory, getSignatureFromTransaction, pipe, createTransactionMessage, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, appendTransactionMessageInstructions, signTransactionMessageWithSigners, createKeyPairSignerFromBytes, isAddress } from '@solana/kit';
6
6
  import { Command } from 'commander';
7
7
  import { generateSecretKey, nip19, getPublicKey } from 'nostr-tools';
8
+ import { execFile } from 'node:child_process';
8
9
  import { realpath, readFile, stat, mkdir, rm, writeFile, rename, unlink } from 'node:fs/promises';
9
10
  import { tmpdir, platform, homedir } from 'node:os';
10
11
  import { dirname, join, resolve, isAbsolute, basename, relative } from 'node:path';
11
- import { readFileSync, mkdtempSync } from 'node:fs';
12
- import { fileURLToPath } from 'node:url';
12
+ import { promisify } from 'node:util';
13
13
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
14
14
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
15
15
  import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
16
16
  import { z, ZodError } from 'zod';
17
17
  import { zodToJsonSchema } from 'zod-to-json-schema';
18
+ import { readFileSync, mkdtempSync } from 'node:fs';
18
19
  import pino from 'pino';
19
- import { execFile } from 'node:child_process';
20
- import { promisify } from 'node:util';
20
+ import { fileURLToPath } from 'node:url';
21
21
  import { randomBytes } from 'node:crypto';
22
22
  import { getTransferSolInstruction } from '@solana-program/system';
23
23
  import { findAssociatedTokenPda, TOKEN_PROGRAM_ADDRESS, getCreateAssociatedTokenIdempotentInstruction, ASSOCIATED_TOKEN_PROGRAM_ADDRESS, getTransferCheckedInstruction } from '@solana-program/token';
@@ -271,108 +271,40 @@ async function writeFileAtomic(path, content, mode = 384) {
271
271
  throw err;
272
272
  }
273
273
  }
274
- var LAMPORTS_PER_SOL = 1000000000n;
275
- function readPackageVersion() {
276
- try {
277
- const here = dirname(fileURLToPath(import.meta.url));
278
- const pkg = JSON.parse(readFileSync(join(here, "..", "package.json"), "utf-8"));
279
- return pkg.version;
280
- } catch {
281
- return "0.0.0";
282
- }
283
- }
284
- var PACKAGE_VERSION = readPackageVersion();
285
- function formatSol(lamports) {
286
- return `${formatSolNumeric(lamports)} SOL`;
287
- }
288
- function formatSolNumeric(lamports) {
289
- const sign = lamports < 0n ? "-" : "";
290
- const abs = lamports < 0n ? -lamports : lamports;
291
- const whole = abs / LAMPORTS_PER_SOL;
292
- const frac = abs % LAMPORTS_PER_SOL;
293
- return `${sign}${whole}.${frac.toString().padStart(9, "0")}`;
294
- }
295
- function assetFromCardPayment(payment2) {
296
- if (!payment2) {
297
- return NATIVE_SOL;
298
- }
299
- const known = resolveKnownAsset(payment2.chain, payment2.token ?? "sol", payment2.mint);
300
- if (known) {
301
- return known;
302
- }
303
- if (payment2.token && payment2.symbol && typeof payment2.decimals === "number") {
304
- return {
305
- chain: payment2.chain,
306
- token: payment2.token,
307
- mint: payment2.mint,
308
- symbol: payment2.symbol,
309
- decimals: payment2.decimals
310
- };
311
- }
312
- return NATIVE_SOL;
313
- }
314
- function parseSolToLamports(s) {
315
- const trimmed = s.trim();
316
- if (!trimmed) {
317
- throw new Error("amount is empty");
318
- }
319
- if (trimmed.startsWith("-")) {
320
- throw new Error("amount cannot be negative");
321
- }
322
- if (!/^(\d+\.\d*|\d*\.\d+|\d+)$/.test(trimmed)) {
323
- throw new Error(
324
- 'amount must be a non-negative decimal number (e.g. "0.5", "1", "0.000000001")'
325
- );
326
- }
327
- const dotPos = trimmed.indexOf(".");
328
- if (dotPos === -1) {
329
- const whole = BigInt(trimmed);
330
- return whole * LAMPORTS_PER_SOL;
331
- }
332
- const wholePart = dotPos === 0 ? 0n : BigInt(trimmed.slice(0, dotPos));
333
- const fracStr = trimmed.slice(dotPos + 1);
334
- if (fracStr.length > 9) {
335
- throw new Error("too many decimal places (max 9)");
336
- }
337
- const padded = fracStr.padEnd(9, "0");
338
- const frac = BigInt(padded);
339
- return wholePart * LAMPORTS_PER_SOL + frac;
340
- }
341
- function checkLen(field, value, max) {
342
- if (new TextEncoder().encode(value).length > max) {
343
- throw new Error(`${field} too long (max ${max} bytes)`);
344
- }
345
- }
346
- var MAX_INPUT_LEN = LIMITS.MAX_INPUT_LENGTH;
347
- var MAX_CAPABILITIES = LIMITS.MAX_CAPABILITIES;
348
- var MAX_TIMEOUT_SECS = LIMITS.MAX_TIMEOUT_SECS;
349
- LIMITS.NIP44_MAX_PLAINTEXT_BYTES;
350
- LIMITS.MAX_ENCRYPTED_INLINE_BYTES;
351
- LIMITS.MAX_REINLINE_TEXT_BYTES;
352
- var MAX_NPUB_LEN = 128;
353
- var MAX_EVENT_ID_LEN = 128;
354
- var MAX_PAYMENT_REQ_LEN = 1e4;
355
- var MAX_SOLANA_ADDR_LEN = 64;
356
- var _paymentStrategy = null;
357
- function payment() {
358
- _paymentStrategy ??= new SolanaPaymentStrategy();
359
- return _paymentStrategy;
360
- }
361
- function decodeNpub(npub) {
362
- const decoded = nip19.decode(npub);
363
- if (decoded.type !== "npub") {
364
- throw new Error(`Expected npub, got ${decoded.type}`);
365
- }
366
- return decoded.data;
367
- }
368
274
 
369
275
  // src/install.ts
276
+ var execFileAsync = promisify(execFile);
370
277
  function elisymPackageArgs() {
371
- return ["-y", `@elisym/mcp@~${PACKAGE_VERSION}`];
278
+ return ["-y", "@elisym/mcp@latest"];
372
279
  }
373
280
  function userHome() {
374
281
  return process.env.HOME ?? homedir();
375
282
  }
283
+ async function resolveNpmCacheDir() {
284
+ const fromEnv = process.env.npm_config_cache;
285
+ if (fromEnv && fromEnv.trim() !== "") {
286
+ return fromEnv.trim();
287
+ }
288
+ try {
289
+ const { stdout } = await execFileAsync("npm", ["config", "get", "cache"]);
290
+ const value = stdout.trim();
291
+ if (value && value !== "undefined" && value !== "null") {
292
+ return value;
293
+ }
294
+ } catch {
295
+ }
296
+ if (platform() === "win32") {
297
+ const localAppData = process.env.LOCALAPPDATA ?? join(userHome(), "AppData", "Local");
298
+ return join(localAppData, "npm-cache");
299
+ }
300
+ return join(userHome(), ".npm");
301
+ }
302
+ async function clearNpxCache() {
303
+ const cacheDir = await resolveNpmCacheDir();
304
+ const npxDir = join(cacheDir, "_npx");
305
+ await rm(npxDir, { recursive: true, force: true });
306
+ console.log(`Cleared npx cache: ${npxDir}`);
307
+ }
376
308
  function validateClientName(name) {
377
309
  if (name === void 0) {
378
310
  return;
@@ -539,7 +471,7 @@ async function runUpdate(options) {
539
471
  try {
540
472
  const result = await updateCodexConfig(path, options.agent);
541
473
  if (result === "updated") {
542
- console.log(`Updated ${client.name}: ${path} -> @elisym/mcp@~${PACKAGE_VERSION}`);
474
+ console.log(`Updated ${client.name}: ${path} -> @elisym/mcp@latest`);
543
475
  updated++;
544
476
  }
545
477
  } catch (err) {
@@ -614,12 +546,15 @@ async function runUpdate(options) {
614
546
  console.log(`Skipped ${client.name}: ${err.message}`);
615
547
  continue;
616
548
  }
617
- console.log(`Updated ${client.name}: ${path} -> @elisym/mcp@~${PACKAGE_VERSION}`);
549
+ console.log(`Updated ${client.name}: ${path} -> @elisym/mcp@latest`);
618
550
  updated++;
619
551
  }
620
552
  if (updated === 0) {
621
553
  console.log("No existing elisym MCP installs found to update.");
622
554
  }
555
+ {
556
+ await clearNpxCache();
557
+ }
623
558
  }
624
559
  async function runUninstall(options) {
625
560
  validateClientName(options.client);
@@ -914,7 +849,10 @@ function updateCodexPackagePin(body) {
914
849
  if (section !== "elisym" || !/^\s*args\s*=/.test(line)) {
915
850
  continue;
916
851
  }
917
- const packageSpec = `@elisym/mcp@~${PACKAGE_VERSION}`;
852
+ const packageSpec = elisymPackageArgs()[1];
853
+ if (packageSpec === void 0) {
854
+ throw new Error("Internal error: missing package argument for elisym MCP install.");
855
+ }
918
856
  const assignmentEndIndex = findTomlAssignmentEnd(lines, lineIndex);
919
857
  const assignmentLines = lines.slice(lineIndex, assignmentEndIndex + 1);
920
858
  const packageLineOffset = assignmentLines.findIndex(
@@ -1526,6 +1464,102 @@ Solana: ${solanaSigner.address}
1526
1464
  }
1527
1465
  })
1528
1466
  ];
1467
+ var LAMPORTS_PER_SOL = 1000000000n;
1468
+ function readPackageVersion() {
1469
+ try {
1470
+ const here = dirname(fileURLToPath(import.meta.url));
1471
+ const pkg = JSON.parse(readFileSync(join(here, "..", "package.json"), "utf-8"));
1472
+ return pkg.version;
1473
+ } catch {
1474
+ return "0.0.0";
1475
+ }
1476
+ }
1477
+ var PACKAGE_VERSION = readPackageVersion();
1478
+ function formatSol(lamports) {
1479
+ return `${formatSolNumeric(lamports)} SOL`;
1480
+ }
1481
+ function formatSolNumeric(lamports) {
1482
+ const sign = lamports < 0n ? "-" : "";
1483
+ const abs = lamports < 0n ? -lamports : lamports;
1484
+ const whole = abs / LAMPORTS_PER_SOL;
1485
+ const frac = abs % LAMPORTS_PER_SOL;
1486
+ return `${sign}${whole}.${frac.toString().padStart(9, "0")}`;
1487
+ }
1488
+ function assetFromCardPayment(payment2) {
1489
+ if (!payment2) {
1490
+ return NATIVE_SOL;
1491
+ }
1492
+ const known = resolveKnownAsset(payment2.chain, payment2.token ?? "sol", payment2.mint);
1493
+ if (known) {
1494
+ return known;
1495
+ }
1496
+ if (payment2.token && payment2.symbol && typeof payment2.decimals === "number") {
1497
+ return {
1498
+ chain: payment2.chain,
1499
+ token: payment2.token,
1500
+ mint: payment2.mint,
1501
+ symbol: payment2.symbol,
1502
+ decimals: payment2.decimals
1503
+ };
1504
+ }
1505
+ return NATIVE_SOL;
1506
+ }
1507
+ function parseSolToLamports(s) {
1508
+ const trimmed = s.trim();
1509
+ if (!trimmed) {
1510
+ throw new Error("amount is empty");
1511
+ }
1512
+ if (trimmed.startsWith("-")) {
1513
+ throw new Error("amount cannot be negative");
1514
+ }
1515
+ if (!/^(\d+\.\d*|\d*\.\d+|\d+)$/.test(trimmed)) {
1516
+ throw new Error(
1517
+ 'amount must be a non-negative decimal number (e.g. "0.5", "1", "0.000000001")'
1518
+ );
1519
+ }
1520
+ const dotPos = trimmed.indexOf(".");
1521
+ if (dotPos === -1) {
1522
+ const whole = BigInt(trimmed);
1523
+ return whole * LAMPORTS_PER_SOL;
1524
+ }
1525
+ const wholePart = dotPos === 0 ? 0n : BigInt(trimmed.slice(0, dotPos));
1526
+ const fracStr = trimmed.slice(dotPos + 1);
1527
+ if (fracStr.length > 9) {
1528
+ throw new Error("too many decimal places (max 9)");
1529
+ }
1530
+ const padded = fracStr.padEnd(9, "0");
1531
+ const frac = BigInt(padded);
1532
+ return wholePart * LAMPORTS_PER_SOL + frac;
1533
+ }
1534
+ function checkLen(field, value, max) {
1535
+ if (new TextEncoder().encode(value).length > max) {
1536
+ throw new Error(`${field} too long (max ${max} bytes)`);
1537
+ }
1538
+ }
1539
+ var MAX_INPUT_LEN = LIMITS.MAX_INPUT_LENGTH;
1540
+ var MAX_CAPABILITIES = LIMITS.MAX_CAPABILITIES;
1541
+ var MAX_TIMEOUT_SECS = LIMITS.MAX_TIMEOUT_SECS;
1542
+ LIMITS.NIP44_MAX_PLAINTEXT_BYTES;
1543
+ LIMITS.MAX_ENCRYPTED_INLINE_BYTES;
1544
+ LIMITS.MAX_REINLINE_TEXT_BYTES;
1545
+ var MAX_NPUB_LEN = 128;
1546
+ var MAX_EVENT_ID_LEN = 128;
1547
+ var MAX_PAYMENT_REQ_LEN = 1e4;
1548
+ var MAX_SOLANA_ADDR_LEN = 64;
1549
+ var _paymentStrategy = null;
1550
+ function payment() {
1551
+ _paymentStrategy ??= new SolanaPaymentStrategy();
1552
+ return _paymentStrategy;
1553
+ }
1554
+ function decodeNpub(npub) {
1555
+ const decoded = nip19.decode(npub);
1556
+ if (decoded.type !== "npub") {
1557
+ throw new Error(`Expected npub, got ${decoded.type}`);
1558
+ }
1559
+ return decoded.data;
1560
+ }
1561
+
1562
+ // src/job-input.ts
1529
1563
  var execFileP = promisify(execFile);
1530
1564
  var MAX_INPUT_PATH_LEN = 4096;
1531
1565
  var SENSITIVE_NAME_RE = /(^|[/\\])(\.secrets\.json|\.env(\..+)?|id_rsa|id_dsa|id_ecdsa|id_ed25519|.*-keypair\.json|.*\.pem|.*\.key|\.bashrc|\.bash_profile|\.bash_login|\.bash_logout|\.bash_aliases|\.profile|\.zshrc|\.zprofile|\.zshenv|\.zlogin|\.zlogout|config\.fish|\.gitconfig|\.npmrc|\.netrc|crontab|sudoers|bash\.bashrc|.*\.service|.*\.desktop)$/i;
@@ -4948,12 +4982,12 @@ program.command("install").description("Install elisym MCP server into client co
4948
4982
  }
4949
4983
  })
4950
4984
  );
4951
- program.command("update").description("Refresh the elisym MCP entry in installed client configs").option(
4985
+ program.command("update").description("Force-refresh installed elisym MCP entries to @latest and clear the npx cache").option(
4952
4986
  "--client <name>",
4953
4987
  "Specific client (claude-desktop, claude-code, cursor, codex, windsurf)"
4954
4988
  ).option("--agent <name>", "Override the agent binding").action(
4955
4989
  safe(async (options) => {
4956
- await runUpdate({ client: options.client, agent: options.agent });
4990
+ await runUpdate({ client: options.client, agent: options.agent, clearCache: true });
4957
4991
  })
4958
4992
  );
4959
4993
  program.command("uninstall").description("Remove elisym from MCP client configs").option("--client <name>", "Specific client").action(