mcp-squared 0.3.0 → 0.3.2

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.
Files changed (3) hide show
  1. package/README.md +15 -0
  2. package/dist/index.js +298 -216
  3. package/package.json +4 -3
package/README.md CHANGED
@@ -27,6 +27,21 @@ npx mcp-squared --help
27
27
  npm exec --yes mcp-squared -- --help
28
28
  ```
29
29
 
30
+ If you see `Cannot find module '@/version.js'`, check for a stale global install:
31
+
32
+ ```bash
33
+ which mcp-squared
34
+ npm ls -g --depth=0 mcp-squared
35
+ ```
36
+
37
+ `mcp-squared@0.3.0` shipped unresolved `@/...` aliases in `dist/index.js`. Remove the old global package and re-run:
38
+
39
+ ```bash
40
+ npm uninstall -g mcp-squared
41
+ hash -r
42
+ npx --yes mcp-squared@latest --help
43
+ ```
44
+
30
45
  ### Install globally
31
46
 
32
47
  ```bash
package/dist/index.js CHANGED
@@ -1,17 +1,13 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
3
  var __defProp = Object.defineProperty;
4
- var __returnValue = (v) => v;
5
- function __exportSetter(name, newValue) {
6
- this[name] = __returnValue.bind(null, newValue);
7
- }
8
4
  var __export = (target, all) => {
9
5
  for (var name in all)
10
6
  __defProp(target, name, {
11
7
  get: all[name],
12
8
  enumerable: true,
13
9
  configurable: true,
14
- set: __exportSetter.bind(all, name)
10
+ set: (newValue) => all[name] = () => newValue
15
11
  });
16
12
  };
17
13
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
@@ -405,7 +401,6 @@ import { randomUUID as randomUUID2 } from "crypto";
405
401
  import { UnauthorizedError as UnauthorizedError4 } from "@modelcontextprotocol/sdk/client/auth.js";
406
402
  import { Client as Client4 } from "@modelcontextprotocol/sdk/client/index.js";
407
403
  import { StreamableHTTPClientTransport as StreamableHTTPClientTransport4 } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
408
- import { VERSION as VERSION4 } from "@/version.js";
409
404
 
410
405
  // src/cli/index.ts
411
406
  function isValidSecurityProfile(value) {
@@ -1433,173 +1428,9 @@ function computeConfigHash(config) {
1433
1428
  }
1434
1429
 
1435
1430
  // src/daemon/proxy.ts
1431
+ init_paths();
1436
1432
  import { spawn } from "child_process";
1437
1433
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
1438
- import { getDaemonSocketPath as getDaemonSocketPath2 } from "@/config/paths.js";
1439
- import {
1440
- loadLiveDaemonRegistry
1441
- } from "@/daemon/registry.js";
1442
- import { SocketClientTransport } from "@/daemon/transport.js";
1443
- var DEFAULT_STARTUP_TIMEOUT_MS = 5000;
1444
- var HEARTBEAT_INTERVAL_MS = 5000;
1445
- function sleep(ms) {
1446
- return new Promise((resolve2) => setTimeout(resolve2, ms));
1447
- }
1448
- async function waitForDaemon(timeoutMs, configHash) {
1449
- const start = Date.now();
1450
- while (Date.now() - start < timeoutMs) {
1451
- const entry = await loadLiveDaemonRegistry(configHash);
1452
- if (entry) {
1453
- return entry;
1454
- }
1455
- await sleep(100);
1456
- }
1457
- return null;
1458
- }
1459
- function spawnDaemonProcess(sharedSecret) {
1460
- const execPath = process.execPath;
1461
- const scriptPath = process.argv[1];
1462
- const args = scriptPath ? [scriptPath, "daemon"] : ["daemon"];
1463
- const child = spawn(execPath, args, {
1464
- detached: true,
1465
- stdio: "ignore",
1466
- env: {
1467
- ...process.env,
1468
- ...sharedSecret ? { MCP_SQUARED_DAEMON_SECRET: sharedSecret } : {}
1469
- }
1470
- });
1471
- child.unref();
1472
- }
1473
- async function createProxyBridge(options) {
1474
- const spawnDaemon = options.spawnDaemon ?? spawnDaemonProcess;
1475
- let endpoint = options.endpoint;
1476
- let sharedSecret = options.sharedSecret?.trim();
1477
- let sessionId = null;
1478
- let heartbeatTimer = null;
1479
- let isOwner = false;
1480
- let daemonClosed = false;
1481
- let stdioClosed = false;
1482
- const debug = options.debug ?? process.env["MCP_SQUARED_PROXY_DEBUG"] === "1";
1483
- if (!endpoint) {
1484
- const registry = await loadLiveDaemonRegistry(options.configHash);
1485
- if (registry) {
1486
- endpoint = registry.endpoint;
1487
- sharedSecret ??= registry.sharedSecret;
1488
- } else if (!options.noSpawn) {
1489
- spawnDaemon(sharedSecret);
1490
- const entry = await waitForDaemon(DEFAULT_STARTUP_TIMEOUT_MS, options.configHash);
1491
- if (!entry) {
1492
- throw new Error("Timed out waiting for daemon to start");
1493
- }
1494
- endpoint = entry.endpoint;
1495
- sharedSecret ??= entry.sharedSecret;
1496
- } else if (options.configHash) {
1497
- endpoint = getDaemonSocketPath2(options.configHash);
1498
- }
1499
- }
1500
- if (!endpoint) {
1501
- throw new Error("Daemon endpoint not available");
1502
- }
1503
- const transportOptions = {
1504
- endpoint
1505
- };
1506
- if (options.timeoutMs !== undefined) {
1507
- transportOptions.timeoutMs = options.timeoutMs;
1508
- }
1509
- const daemonTransport = new SocketClientTransport(transportOptions);
1510
- const stdioTransport = options.stdioTransport;
1511
- const closeDaemon = async (sendGoodbye) => {
1512
- if (daemonClosed) {
1513
- return;
1514
- }
1515
- daemonClosed = true;
1516
- if (sendGoodbye && sessionId) {
1517
- await daemonTransport.sendControl({ type: "goodbye", sessionId }).catch(() => {});
1518
- }
1519
- await daemonTransport.close().catch(() => {});
1520
- };
1521
- daemonTransport.oncontrol = (message) => {
1522
- switch (message.type) {
1523
- case "helloAck":
1524
- sessionId = message.sessionId;
1525
- isOwner = message.isOwner;
1526
- if (debug) {
1527
- console.error(`[proxy] session ${message.sessionId} owner=${message.isOwner}`);
1528
- }
1529
- break;
1530
- case "ownerChanged":
1531
- isOwner = message.ownerSessionId === sessionId;
1532
- if (debug) {
1533
- console.error(`[proxy] owner changed: ${message.ownerSessionId} (isOwner=${isOwner})`);
1534
- }
1535
- break;
1536
- }
1537
- };
1538
- daemonTransport.onmessage = (message) => {
1539
- stdioTransport.send(message);
1540
- };
1541
- daemonTransport.onclose = () => {
1542
- daemonClosed = true;
1543
- if (heartbeatTimer) {
1544
- clearInterval(heartbeatTimer);
1545
- heartbeatTimer = null;
1546
- }
1547
- stdioTransport.close();
1548
- };
1549
- daemonTransport.onerror = (error) => {
1550
- console.error(`Daemon transport error: ${error.message}`);
1551
- };
1552
- stdioTransport.onmessage = (message) => {
1553
- daemonTransport.send(message);
1554
- };
1555
- stdioTransport.onclose = () => {
1556
- stdioClosed = true;
1557
- if (heartbeatTimer) {
1558
- clearInterval(heartbeatTimer);
1559
- heartbeatTimer = null;
1560
- }
1561
- closeDaemon(true);
1562
- };
1563
- stdioTransport.onerror = (error) => {
1564
- console.error(`Stdio transport error: ${error.message}`);
1565
- };
1566
- await daemonTransport.start();
1567
- const launcherHint = process.env["MCP_SQUARED_LAUNCHER"] ?? process.env["MCP_CLIENT_NAME"] ?? process.env["MCP_SQUARED_AGENT"];
1568
- const clientId = launcherHint ? `${launcherHint}-${process.pid}` : `proxy-${process.pid}`;
1569
- daemonTransport.sendControl({
1570
- type: "hello",
1571
- clientId,
1572
- ...sharedSecret ? { sharedSecret } : {}
1573
- });
1574
- heartbeatTimer = setInterval(() => {
1575
- if (!sessionId) {
1576
- return;
1577
- }
1578
- daemonTransport.sendControl({
1579
- type: "heartbeat",
1580
- sessionId
1581
- });
1582
- }, options.heartbeatIntervalMs ?? HEARTBEAT_INTERVAL_MS);
1583
- await stdioTransport.start();
1584
- return {
1585
- stop: async () => {
1586
- if (heartbeatTimer) {
1587
- clearInterval(heartbeatTimer);
1588
- heartbeatTimer = null;
1589
- }
1590
- await closeDaemon(true);
1591
- if (!stdioClosed) {
1592
- await stdioTransport.close();
1593
- }
1594
- }
1595
- };
1596
- }
1597
- async function runProxy(options = {}) {
1598
- return createProxyBridge({
1599
- ...options,
1600
- stdioTransport: new StdioServerTransport
1601
- });
1602
- }
1603
1434
 
1604
1435
  // src/daemon/registry.ts
1605
1436
  init_paths();
@@ -1698,7 +1529,7 @@ async function isDaemonAlive(entry, timeoutMs = DEFAULT_CONNECT_TIMEOUT_MS2) {
1698
1529
  }
1699
1530
  return canConnect2(entry.endpoint, timeoutMs);
1700
1531
  }
1701
- async function loadLiveDaemonRegistry2(configHash) {
1532
+ async function loadLiveDaemonRegistry(configHash) {
1702
1533
  const entry = readDaemonRegistry(configHash);
1703
1534
  if (!entry) {
1704
1535
  return null;
@@ -1711,20 +1542,8 @@ async function loadLiveDaemonRegistry2(configHash) {
1711
1542
  return entry;
1712
1543
  }
1713
1544
 
1714
- // src/daemon/server.ts
1715
- init_paths();
1716
- import { randomUUID } from "crypto";
1717
- import { existsSync as existsSync4, mkdirSync as mkdirSync3, unlinkSync as unlinkSync3 } from "fs";
1718
- import {
1719
- connect as connect3,
1720
- createServer,
1721
- isIPv4,
1722
- isIPv6
1723
- } from "net";
1724
- import { dirname as dirname2 } from "path";
1725
- import { VERSION } from "@/version.js";
1726
-
1727
1545
  // src/daemon/transport.ts
1546
+ import { connect as connect3 } from "net";
1728
1547
  var HEADER_LENGTH = 4;
1729
1548
  function encodeFrame(message) {
1730
1549
  const payload = Buffer.from(JSON.stringify(message), "utf8");
@@ -1822,10 +1641,275 @@ class SocketServerTransport extends BaseSocketTransport {
1822
1641
  this.socket = socket;
1823
1642
  }
1824
1643
  }
1644
+ function isTcpEndpoint3(endpoint) {
1645
+ return endpoint.startsWith("tcp://");
1646
+ }
1647
+ function parseTcpEndpoint3(endpoint) {
1648
+ const url = new URL(endpoint);
1649
+ if (url.protocol !== "tcp:") {
1650
+ throw new Error(`Invalid TCP endpoint protocol: ${url.protocol}`);
1651
+ }
1652
+ const host = url.hostname;
1653
+ const port = Number.parseInt(url.port, 10);
1654
+ if (!host || Number.isNaN(port)) {
1655
+ throw new Error(`Invalid TCP endpoint: ${endpoint}`);
1656
+ }
1657
+ return { host, port };
1658
+ }
1659
+
1660
+ class SocketClientTransport extends BaseSocketTransport {
1661
+ endpoint;
1662
+ timeoutMs;
1663
+ constructor(options) {
1664
+ super();
1665
+ this.endpoint = options.endpoint;
1666
+ this.timeoutMs = options.timeoutMs ?? 5000;
1667
+ }
1668
+ async start() {
1669
+ if (this.started) {
1670
+ return;
1671
+ }
1672
+ await new Promise((resolve2, reject) => {
1673
+ const socket = isTcpEndpoint3(this.endpoint) ? connect3(parseTcpEndpoint3(this.endpoint)) : connect3(this.endpoint);
1674
+ this.socket = socket;
1675
+ const timeoutId = setTimeout(() => {
1676
+ socket.destroy();
1677
+ reject(new Error(`Connection timeout after ${this.timeoutMs}ms`));
1678
+ }, this.timeoutMs);
1679
+ socket.once("connect", () => {
1680
+ clearTimeout(timeoutId);
1681
+ this.started = true;
1682
+ this.attachHandlers();
1683
+ resolve2();
1684
+ });
1685
+ socket.once("error", (error) => {
1686
+ clearTimeout(timeoutId);
1687
+ reject(error);
1688
+ });
1689
+ });
1690
+ }
1691
+ }
1692
+
1693
+ // src/daemon/proxy.ts
1694
+ var DEFAULT_STARTUP_TIMEOUT_MS = 5000;
1695
+ var HEARTBEAT_INTERVAL_MS = 5000;
1696
+ function sleep(ms) {
1697
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
1698
+ }
1699
+ async function waitForDaemon(timeoutMs, configHash) {
1700
+ const start = Date.now();
1701
+ while (Date.now() - start < timeoutMs) {
1702
+ const entry = await loadLiveDaemonRegistry(configHash);
1703
+ if (entry) {
1704
+ return entry;
1705
+ }
1706
+ await sleep(100);
1707
+ }
1708
+ return null;
1709
+ }
1710
+ function spawnDaemonProcess(sharedSecret) {
1711
+ const execPath = process.execPath;
1712
+ const scriptPath = process.argv[1];
1713
+ const args = scriptPath ? [scriptPath, "daemon"] : ["daemon"];
1714
+ const child = spawn(execPath, args, {
1715
+ detached: true,
1716
+ stdio: "ignore",
1717
+ env: {
1718
+ ...process.env,
1719
+ ...sharedSecret ? { MCP_SQUARED_DAEMON_SECRET: sharedSecret } : {}
1720
+ }
1721
+ });
1722
+ child.unref();
1723
+ }
1724
+ async function createProxyBridge(options) {
1725
+ const spawnDaemon = options.spawnDaemon ?? spawnDaemonProcess;
1726
+ let endpoint = options.endpoint;
1727
+ let sharedSecret = options.sharedSecret?.trim();
1728
+ let sessionId = null;
1729
+ let heartbeatTimer = null;
1730
+ let isOwner = false;
1731
+ let daemonClosed = false;
1732
+ let stdioClosed = false;
1733
+ const debug = options.debug ?? process.env["MCP_SQUARED_PROXY_DEBUG"] === "1";
1734
+ if (!endpoint) {
1735
+ const registry = await loadLiveDaemonRegistry(options.configHash);
1736
+ if (registry) {
1737
+ endpoint = registry.endpoint;
1738
+ sharedSecret ??= registry.sharedSecret;
1739
+ } else if (!options.noSpawn) {
1740
+ spawnDaemon(sharedSecret);
1741
+ const entry = await waitForDaemon(DEFAULT_STARTUP_TIMEOUT_MS, options.configHash);
1742
+ if (!entry) {
1743
+ throw new Error("Timed out waiting for daemon to start");
1744
+ }
1745
+ endpoint = entry.endpoint;
1746
+ sharedSecret ??= entry.sharedSecret;
1747
+ } else if (options.configHash) {
1748
+ endpoint = getDaemonSocketPath(options.configHash);
1749
+ }
1750
+ }
1751
+ if (!endpoint) {
1752
+ throw new Error("Daemon endpoint not available");
1753
+ }
1754
+ const transportOptions = {
1755
+ endpoint
1756
+ };
1757
+ if (options.timeoutMs !== undefined) {
1758
+ transportOptions.timeoutMs = options.timeoutMs;
1759
+ }
1760
+ const daemonTransport = new SocketClientTransport(transportOptions);
1761
+ const stdioTransport = options.stdioTransport;
1762
+ const closeDaemon = async (sendGoodbye) => {
1763
+ if (daemonClosed) {
1764
+ return;
1765
+ }
1766
+ daemonClosed = true;
1767
+ if (sendGoodbye && sessionId) {
1768
+ await daemonTransport.sendControl({ type: "goodbye", sessionId }).catch(() => {});
1769
+ }
1770
+ await daemonTransport.close().catch(() => {});
1771
+ };
1772
+ daemonTransport.oncontrol = (message) => {
1773
+ switch (message.type) {
1774
+ case "helloAck":
1775
+ sessionId = message.sessionId;
1776
+ isOwner = message.isOwner;
1777
+ if (debug) {
1778
+ console.error(`[proxy] session ${message.sessionId} owner=${message.isOwner}`);
1779
+ }
1780
+ break;
1781
+ case "ownerChanged":
1782
+ isOwner = message.ownerSessionId === sessionId;
1783
+ if (debug) {
1784
+ console.error(`[proxy] owner changed: ${message.ownerSessionId} (isOwner=${isOwner})`);
1785
+ }
1786
+ break;
1787
+ }
1788
+ };
1789
+ daemonTransport.onmessage = (message) => {
1790
+ stdioTransport.send(message);
1791
+ };
1792
+ daemonTransport.onclose = () => {
1793
+ daemonClosed = true;
1794
+ if (heartbeatTimer) {
1795
+ clearInterval(heartbeatTimer);
1796
+ heartbeatTimer = null;
1797
+ }
1798
+ stdioTransport.close();
1799
+ };
1800
+ daemonTransport.onerror = (error) => {
1801
+ console.error(`Daemon transport error: ${error.message}`);
1802
+ };
1803
+ stdioTransport.onmessage = (message) => {
1804
+ daemonTransport.send(message);
1805
+ };
1806
+ stdioTransport.onclose = () => {
1807
+ stdioClosed = true;
1808
+ if (heartbeatTimer) {
1809
+ clearInterval(heartbeatTimer);
1810
+ heartbeatTimer = null;
1811
+ }
1812
+ closeDaemon(true);
1813
+ };
1814
+ stdioTransport.onerror = (error) => {
1815
+ console.error(`Stdio transport error: ${error.message}`);
1816
+ };
1817
+ await daemonTransport.start();
1818
+ const launcherHint = process.env["MCP_SQUARED_LAUNCHER"] ?? process.env["MCP_CLIENT_NAME"] ?? process.env["MCP_SQUARED_AGENT"];
1819
+ const clientId = launcherHint ? `${launcherHint}-${process.pid}` : `proxy-${process.pid}`;
1820
+ daemonTransport.sendControl({
1821
+ type: "hello",
1822
+ clientId,
1823
+ ...sharedSecret ? { sharedSecret } : {}
1824
+ });
1825
+ heartbeatTimer = setInterval(() => {
1826
+ if (!sessionId) {
1827
+ return;
1828
+ }
1829
+ daemonTransport.sendControl({
1830
+ type: "heartbeat",
1831
+ sessionId
1832
+ });
1833
+ }, options.heartbeatIntervalMs ?? HEARTBEAT_INTERVAL_MS);
1834
+ await stdioTransport.start();
1835
+ return {
1836
+ stop: async () => {
1837
+ if (heartbeatTimer) {
1838
+ clearInterval(heartbeatTimer);
1839
+ heartbeatTimer = null;
1840
+ }
1841
+ await closeDaemon(true);
1842
+ if (!stdioClosed) {
1843
+ await stdioTransport.close();
1844
+ }
1845
+ }
1846
+ };
1847
+ }
1848
+ async function runProxy(options = {}) {
1849
+ return createProxyBridge({
1850
+ ...options,
1851
+ stdioTransport: new StdioServerTransport
1852
+ });
1853
+ }
1854
+
1855
+ // src/daemon/server.ts
1856
+ init_paths();
1857
+ import { randomUUID } from "crypto";
1858
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3, unlinkSync as unlinkSync3 } from "fs";
1859
+ import {
1860
+ connect as connect4,
1861
+ createServer,
1862
+ isIPv4,
1863
+ isIPv6
1864
+ } from "net";
1865
+ import { dirname as dirname2 } from "path";
1866
+
1867
+ // src/version.ts
1868
+ import { readFileSync as readFileSync3 } from "fs";
1869
+ import { createRequire } from "module";
1870
+ function normalizeVersion(value) {
1871
+ if (typeof value !== "string") {
1872
+ return;
1873
+ }
1874
+ const trimmed = value.trim();
1875
+ return trimmed.length > 0 ? trimmed : undefined;
1876
+ }
1877
+ function readManifestFile(manifestUrl) {
1878
+ const raw = readFileSync3(manifestUrl, "utf8");
1879
+ return JSON.parse(raw);
1880
+ }
1881
+ function readBundledManifestFile() {
1882
+ const require2 = createRequire(import.meta.url);
1883
+ return require2("../package.json");
1884
+ }
1885
+ function resolveVersion(options = {}) {
1886
+ const readManifest = options.readManifest ?? readManifestFile;
1887
+ const manifestUrl = options.manifestUrl ?? new URL("../package.json", import.meta.url);
1888
+ try {
1889
+ const manifest = readManifest(manifestUrl);
1890
+ const manifestVersion = normalizeVersion(manifest.version);
1891
+ if (manifestVersion) {
1892
+ return manifestVersion;
1893
+ }
1894
+ } catch {}
1895
+ const envVersion = normalizeVersion((options.env ?? process.env)["npm_package_version"]);
1896
+ if (envVersion) {
1897
+ return envVersion;
1898
+ }
1899
+ const readBundledManifest = options.readBundledManifest ?? readBundledManifestFile;
1900
+ try {
1901
+ const bundledVersion = normalizeVersion(readBundledManifest().version);
1902
+ if (bundledVersion) {
1903
+ return bundledVersion;
1904
+ }
1905
+ } catch {}
1906
+ return normalizeVersion(options.fallbackVersion) ?? "0.0.0";
1907
+ }
1908
+ var VERSION = resolveVersion();
1825
1909
 
1826
1910
  // src/daemon/server.ts
1827
1911
  var DEFAULT_CONNECT_TIMEOUT_MS3 = 300;
1828
- function isTcpEndpoint3(endpoint) {
1912
+ function isTcpEndpoint4(endpoint) {
1829
1913
  return endpoint.startsWith("tcp://");
1830
1914
  }
1831
1915
  function parseMappedIpv4Address(normalizedHost) {
@@ -1850,7 +1934,7 @@ function parseMappedIpv4Address(normalizedHost) {
1850
1934
  }
1851
1935
  return `${high >> 8 & 255}.${high & 255}.${low >> 8 & 255}.${low & 255}`;
1852
1936
  }
1853
- function parseTcpEndpoint3(endpoint) {
1937
+ function parseTcpEndpoint4(endpoint) {
1854
1938
  const url = new URL(endpoint);
1855
1939
  if (url.protocol !== "tcp:") {
1856
1940
  throw new Error(`Invalid TCP endpoint protocol: ${url.protocol}`);
@@ -1898,7 +1982,7 @@ function formatTcpEndpoint(host, port) {
1898
1982
  return `tcp://${normalized}:${port}`;
1899
1983
  }
1900
1984
  function assertLoopbackTcpEndpoint(endpoint) {
1901
- const { host } = parseTcpEndpoint3(endpoint);
1985
+ const { host } = parseTcpEndpoint4(endpoint);
1902
1986
  if (!isLoopbackHost(host)) {
1903
1987
  throw new Error(`Refusing non-loopback daemon TCP endpoint: ${endpoint}. Use localhost, 127.0.0.1, or ::1.`);
1904
1988
  }
@@ -1907,7 +1991,7 @@ async function canConnect3(endpoint, timeoutMs = DEFAULT_CONNECT_TIMEOUT_MS3) {
1907
1991
  return new Promise((resolve2) => {
1908
1992
  let socket = null;
1909
1993
  try {
1910
- socket = isTcpEndpoint3(endpoint) ? connect3(parseTcpEndpoint3(endpoint)) : connect3(endpoint);
1994
+ socket = isTcpEndpoint4(endpoint) ? connect4(parseTcpEndpoint4(endpoint)) : connect4(endpoint);
1911
1995
  } catch {
1912
1996
  resolve2(false);
1913
1997
  return;
@@ -1962,7 +2046,7 @@ class DaemonServer {
1962
2046
  return;
1963
2047
  }
1964
2048
  ensureDaemonDir(this.configHash);
1965
- const tcp = isTcpEndpoint3(this.socketPath);
2049
+ const tcp = isTcpEndpoint4(this.socketPath);
1966
2050
  if (tcp) {
1967
2051
  assertLoopbackTcpEndpoint(this.socketPath);
1968
2052
  }
@@ -1970,7 +2054,7 @@ class DaemonServer {
1970
2054
  mkdirSync3(dirname2(this.socketPath), { recursive: true });
1971
2055
  }
1972
2056
  if (tcp) {
1973
- const port = parseTcpEndpoint3(this.socketPath).port;
2057
+ const port = parseTcpEndpoint4(this.socketPath).port;
1974
2058
  if (port > 0 && await canConnect3(this.socketPath)) {
1975
2059
  throw new Error(`Daemon already running at ${this.socketPath}. Refusing to start another.`);
1976
2060
  }
@@ -1990,7 +2074,7 @@ class DaemonServer {
1990
2074
  await new Promise((resolve2, reject) => {
1991
2075
  this.server?.once("error", (error) => reject(error));
1992
2076
  if (tcp) {
1993
- const { host, port } = parseTcpEndpoint3(this.socketPath);
2077
+ const { host, port } = parseTcpEndpoint4(this.socketPath);
1994
2078
  if (!host || Number.isNaN(port)) {
1995
2079
  reject(new Error(`Invalid TCP endpoint: ${this.socketPath}`));
1996
2080
  return;
@@ -3667,7 +3751,7 @@ function promptUser(question) {
3667
3751
  }
3668
3752
 
3669
3753
  // src/install/runner.ts
3670
- import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
3754
+ import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
3671
3755
  import { dirname as dirname3 } from "path";
3672
3756
  import { createInterface } from "readline";
3673
3757
  import { parse as parseToml3, stringify as stringifyToml2 } from "smol-toml";
@@ -3987,7 +4071,7 @@ function performInstallation(options) {
3987
4071
  if (existsSync7(path)) {
3988
4072
  configExists = true;
3989
4073
  try {
3990
- const content = readFileSync3(path, "utf-8");
4074
+ const content = readFileSync4(path, "utf-8");
3991
4075
  existingConfig = isToml ? parseToml3(content) : JSON.parse(content);
3992
4076
  } catch (error) {
3993
4077
  return {
@@ -4404,7 +4488,6 @@ class OAuthCallbackServer {
4404
4488
  import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
4405
4489
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
4406
4490
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
4407
- import { VERSION as VERSION2 } from "@/version.js";
4408
4491
 
4409
4492
  // src/oauth/provider.ts
4410
4493
  var DEFAULT_OAUTH_CALLBACK_PORT = 8089;
@@ -4575,7 +4658,7 @@ import {
4575
4658
  chmodSync,
4576
4659
  existsSync as existsSync8,
4577
4660
  mkdirSync as mkdirSync5,
4578
- readFileSync as readFileSync4,
4661
+ readFileSync as readFileSync5,
4579
4662
  unlinkSync as unlinkSync4,
4580
4663
  writeFileSync as writeFileSync4
4581
4664
  } from "fs";
@@ -4613,7 +4696,7 @@ class TokenStorage {
4613
4696
  return;
4614
4697
  }
4615
4698
  try {
4616
- const content = readFileSync4(filePath, "utf-8");
4699
+ const content = readFileSync5(filePath, "utf-8");
4617
4700
  return JSON.parse(content);
4618
4701
  } catch {
4619
4702
  return;
@@ -4695,7 +4778,7 @@ class TokenStorage {
4695
4778
  function getPreflightClientMetadata() {
4696
4779
  return {
4697
4780
  name: "mcp-squared-preflight",
4698
- version: VERSION2
4781
+ version: VERSION
4699
4782
  };
4700
4783
  }
4701
4784
  async function performPreflightAuth(config) {
@@ -4800,7 +4883,6 @@ async function performInteractiveAuth(name, sseConfig, authProvider, callbackPor
4800
4883
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4801
4884
  import { StdioServerTransport as StdioServerTransport2 } from "@modelcontextprotocol/sdk/server/stdio.js";
4802
4885
  import { z as z3 } from "zod";
4803
- import { VERSION as VERSION3 } from "@/version.js";
4804
4886
 
4805
4887
  // agent_safety_kit/policy/matchers.ts
4806
4888
  var GLOB_SPECIALS = /[.+^${}()|[\]\\]/g;
@@ -5158,7 +5240,7 @@ class Guard {
5158
5240
  }
5159
5241
  }
5160
5242
  // agent_safety_kit/policy/load.ts
5161
- import { existsSync as existsSync9, readFileSync as readFileSync5 } from "fs";
5243
+ import { existsSync as existsSync9, readFileSync as readFileSync6 } from "fs";
5162
5244
  import { resolve as resolve3 } from "path";
5163
5245
  import { parse as parseYaml } from "yaml";
5164
5246
 
@@ -5221,7 +5303,7 @@ function load_policy(options = {}) {
5221
5303
  if (!existsSync9(sourcePath)) {
5222
5304
  throw new Error(`Agent safety policy file not found at ${sourcePath}`);
5223
5305
  }
5224
- const raw = readFileSync5(sourcePath, "utf8");
5306
+ const raw = readFileSync6(sourcePath, "utf8");
5225
5307
  const parsed = parseYaml(raw);
5226
5308
  const policy = AgentPolicySchema.parse(parsed);
5227
5309
  const playbookName = options.playbook ?? envConfig.playbook;
@@ -5258,7 +5340,7 @@ class NullSink {
5258
5340
  }
5259
5341
 
5260
5342
  // agent_safety_kit/observability/sinks/otel.ts
5261
- import { createRequire } from "module";
5343
+ import { createRequire as createRequire2 } from "module";
5262
5344
 
5263
5345
  // agent_safety_kit/observability/sinks/base.ts
5264
5346
  function compactAttributes(attributes) {
@@ -5275,7 +5357,7 @@ function compactAttributes(attributes) {
5275
5357
  }
5276
5358
 
5277
5359
  // agent_safety_kit/observability/sinks/otel.ts
5278
- var require2 = createRequire(import.meta.url);
5360
+ var require2 = createRequire2(import.meta.url);
5279
5361
  function loadOpenTelemetryApi() {
5280
5362
  try {
5281
5363
  return require2("@opentelemetry/api");
@@ -7154,10 +7236,10 @@ async function testUpstreamConnection(name, config, options = {}) {
7154
7236
  // src/server/monitor-server.ts
7155
7237
  import { existsSync as existsSync10, unlinkSync as unlinkSync5 } from "fs";
7156
7238
  import { createServer as createServer3 } from "net";
7157
- function isTcpEndpoint4(endpoint) {
7239
+ function isTcpEndpoint5(endpoint) {
7158
7240
  return endpoint.startsWith("tcp://");
7159
7241
  }
7160
- function parseTcpEndpoint4(endpoint) {
7242
+ function parseTcpEndpoint5(endpoint) {
7161
7243
  let url;
7162
7244
  try {
7163
7245
  url = new URL(endpoint);
@@ -7197,7 +7279,7 @@ class MonitorServer {
7197
7279
  if (this.isRunning) {
7198
7280
  return;
7199
7281
  }
7200
- const tcp = isTcpEndpoint4(this.socketPath);
7282
+ const tcp = isTcpEndpoint5(this.socketPath);
7201
7283
  if (!tcp && existsSync10(this.socketPath)) {
7202
7284
  try {
7203
7285
  unlinkSync5(this.socketPath);
@@ -7218,7 +7300,7 @@ class MonitorServer {
7218
7300
  reject(error);
7219
7301
  });
7220
7302
  if (tcp) {
7221
- const { host, port } = parseTcpEndpoint4(this.socketPath);
7303
+ const { host, port } = parseTcpEndpoint5(this.socketPath);
7222
7304
  server.listen({ host, port }, () => {
7223
7305
  const address = server.address();
7224
7306
  if (address && typeof address !== "string") {
@@ -7252,7 +7334,7 @@ class MonitorServer {
7252
7334
  }
7253
7335
  });
7254
7336
  });
7255
- if (!isTcpEndpoint4(this.socketPath)) {
7337
+ if (!isTcpEndpoint5(this.socketPath)) {
7256
7338
  try {
7257
7339
  if (existsSync10(this.socketPath)) {
7258
7340
  unlinkSync5(this.socketPath);
@@ -7609,7 +7691,7 @@ class McpSquaredServer {
7609
7691
  guard;
7610
7692
  constructor(options = {}) {
7611
7693
  const name = options.name ?? "mcp-squared";
7612
- const version = options.version ?? VERSION3;
7694
+ const version = options.version ?? VERSION;
7613
7695
  this.serverName = name;
7614
7696
  this.serverVersion = version;
7615
7697
  if (options.cataloger) {
@@ -8186,7 +8268,7 @@ async function startServer() {
8186
8268
  startedAt: Date.now(),
8187
8269
  cwd: process.cwd(),
8188
8270
  configPath,
8189
- version: VERSION4,
8271
+ version: VERSION,
8190
8272
  command: process.argv.join(" "),
8191
8273
  role: "server",
8192
8274
  ...launcher ? { launcher } : {}
@@ -8413,7 +8495,7 @@ Callback URL: ${callbackServer.getCallbackUrl()}`);
8413
8495
  });
8414
8496
  const client = new Client4({
8415
8497
  name: "mcp-squared-auth",
8416
- version: VERSION4
8498
+ version: VERSION
8417
8499
  });
8418
8500
  console.log(`
8419
8501
  Connecting to server...`);
@@ -8476,7 +8558,7 @@ async function runMonitor(options) {
8476
8558
  if (!socketPath) {
8477
8559
  const { config, path: configPath } = await loadConfig();
8478
8560
  const configHash = computeConfigHash(config);
8479
- const daemonRegistry = await loadLiveDaemonRegistry2(configHash);
8561
+ const daemonRegistry = await loadLiveDaemonRegistry(configHash);
8480
8562
  if (!daemonRegistry) {
8481
8563
  console.error("Error: No running shared MCP\xB2 daemon found for the active configuration.");
8482
8564
  console.error("Start the daemon first:");
@@ -8690,7 +8772,7 @@ async function runDaemon(options) {
8690
8772
  startedAt: Date.now(),
8691
8773
  cwd: process.cwd(),
8692
8774
  configPath,
8693
- version: VERSION4,
8775
+ version: VERSION,
8694
8776
  command: process.argv.join(" "),
8695
8777
  role: "daemon",
8696
8778
  ...daemonLauncher ? { launcher: daemonLauncher } : {}
@@ -8743,7 +8825,7 @@ async function runProxyCommand(options) {
8743
8825
  startedAt: Date.now(),
8744
8826
  cwd: process.cwd(),
8745
8827
  configPath,
8746
- version: VERSION4,
8828
+ version: VERSION,
8747
8829
  command: process.argv.join(" "),
8748
8830
  role: "proxy",
8749
8831
  ...proxyLauncher ? { launcher: proxyLauncher } : {}
@@ -8818,7 +8900,7 @@ async function main(argv = process.argv.slice(2)) {
8818
8900
  process.exit(0);
8819
8901
  }
8820
8902
  if (args.version) {
8821
- console.log(`MCP\xB2 v${VERSION4}`);
8903
+ console.log(`MCP\xB2 v${VERSION}`);
8822
8904
  process.exit(0);
8823
8905
  }
8824
8906
  switch (args.mode) {
@@ -8888,5 +8970,5 @@ export {
8888
8970
  main,
8889
8971
  logSecurityProfile,
8890
8972
  logSearchModeProfile,
8891
- VERSION4 as VERSION
8973
+ VERSION
8892
8974
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-squared",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "MCP² (Mercury Control Plane) - A local-first meta-server and proxy for the Model Context Protocol",
5
5
  "author": "aditzel",
6
6
  "license": "Apache-2.0",
@@ -22,14 +22,15 @@
22
22
  "build": "bun build src/index.ts --outdir dist --target bun --packages=external",
23
23
  "build:compile": "bun build src/index.ts --compile --outfile dist/mcp-squared --external @opentui/core --external @opentui/core-darwin-arm64 --external @opentui/core-darwin-x64 --external @opentui/core-linux-arm64 --external @opentui/core-linux-x64 --external @opentui/core-win32-arm64 --external @opentui/core-win32-x64",
24
24
  "build:compile:matrix": "bash scripts/compile-matrix.sh",
25
- "prepack": "bun run build",
25
+ "prepack": "bun run build && bun run build:verify",
26
26
  "audit": "bun audit",
27
27
  "test": "bun test",
28
28
  "test:fast": "SKIP_SLOW_TESTS=true bun test",
29
29
  "test:watch": "bun test --watch",
30
30
  "typecheck": "tsc --noEmit",
31
31
  "lint": "biome check src tests scripts AGENTS.md CLAUDE.md WARP.md README.md CHANGELOG.md package.json biome.json tsconfig.json",
32
- "release:check": "bun run audit && bun test && bun run build && bun run lint && bun run typecheck && bun pm pack --dry-run",
32
+ "release:check": "bun run audit && bun test && bun run build && bun run build:verify && bun run lint && bun run typecheck && bun pm pack --dry-run",
33
+ "build:verify": "bun run scripts/verify-dist-runtime-imports.ts",
33
34
  "lint:fix": "biome check --write .",
34
35
  "format": "biome format --write .",
35
36
  "clean": "rm -rf dist",