mcp-proxy 5.5.6 → 5.6.1

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
@@ -37,6 +37,7 @@ options:
37
37
  - `--port`: Specify the port to listen on (default: 8080)
38
38
  - `--debug`: Enable debug logging
39
39
  - `--shell`: Spawn the server via the user's shell
40
+ - `--apiKey`: API key for authenticating requests (uses X-API-Key header)
40
41
 
41
42
  ### Passing arguments to the wrapped command
42
43
 
@@ -83,6 +84,64 @@ npx mcp-proxy --port 8080 --stateless --server stream tsx server.js
83
84
  - **Request isolation**: When you need complete independence between requests
84
85
  - **Simple deployments**: When you don't need to maintain connection state
85
86
 
87
+ ### API Key Authentication
88
+
89
+ MCP Proxy supports optional API key authentication to secure your endpoints. When enabled, clients must provide a valid API key in the `X-API-Key` header to access the proxy.
90
+
91
+ #### Enabling Authentication
92
+
93
+ Authentication is disabled by default for backward compatibility. To enable it, provide an API key via:
94
+
95
+ **Command-line:**
96
+ ```bash
97
+ npx mcp-proxy --port 8080 --apiKey "your-secret-key" tsx server.js
98
+ ```
99
+
100
+ **Environment variable:**
101
+ ```bash
102
+ export MCP_PROXY_API_KEY="your-secret-key"
103
+ npx mcp-proxy --port 8080 tsx server.js
104
+ ```
105
+
106
+ #### Client Configuration
107
+
108
+ Clients must include the API key in the `X-API-Key` header:
109
+
110
+ ```typescript
111
+ // For streamable HTTP transport
112
+ const transport = new StreamableHTTPClientTransport(
113
+ new URL('http://localhost:8080/mcp'),
114
+ {
115
+ headers: {
116
+ 'X-API-Key': 'your-secret-key'
117
+ }
118
+ }
119
+ );
120
+
121
+ // For SSE transport
122
+ const transport = new SSEClientTransport(
123
+ new URL('http://localhost:8080/sse'),
124
+ {
125
+ headers: {
126
+ 'X-API-Key': 'your-secret-key'
127
+ }
128
+ }
129
+ );
130
+ ```
131
+
132
+ #### Exempt Endpoints
133
+
134
+ The following endpoints do not require authentication:
135
+ - `/ping` - Health check endpoint
136
+ - `OPTIONS` requests - CORS preflight requests
137
+
138
+ #### Security Notes
139
+
140
+ - **Use HTTPS in production**: API keys should only be transmitted over secure connections
141
+ - **Keep keys secure**: Never commit API keys to version control
142
+ - **Generate strong keys**: Use cryptographically secure random strings for API keys
143
+ - **Rotate keys regularly**: Change API keys periodically for better security
144
+
86
145
  ### Node.js SDK
87
146
 
88
147
  The Node.js SDK provides several utilities that are used to create a proxy.
@@ -137,6 +196,7 @@ Options:
137
196
  - `sseEndpoint`: SSE endpoint path (default: "/sse", set to null to disable)
138
197
  - `streamEndpoint`: Streamable HTTP endpoint path (default: "/mcp", set to null to disable)
139
198
  - `stateless`: Enable stateless mode for HTTP streamable transport (default: false)
199
+ - `apiKey`: API key for authenticating requests (optional)
140
200
  - `onConnect`: Callback when a server connects (optional)
141
201
  - `onClose`: Callback when a server disconnects (optional)
142
202
  - `onUnhandledRequest`: Callback for unhandled HTTP requests (optional)
@@ -1,2 +1 @@
1
- #!/usr/bin/env node
2
- export {};
1
+ export { };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { Client, InMemoryEventStore, ReadBuffer, Server, __commonJS, __toESM, proxyServer, serializeMessage, startHTTPServer } from "../stdio-CQWnvum1.js";
2
+ import { Client, InMemoryEventStore, ReadBuffer, Server, __commonJS, __toESM, proxyServer, serializeMessage, startHTTPServer } from "../stdio-D0Lv8ytu.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { basename, dirname, extname, join, normalize, relative, resolve } from "path";
5
5
  import { format, inspect } from "util";
@@ -507,7 +507,6 @@ var UI = class {
507
507
  remainingWidth -= col.width;
508
508
  return col.width;
509
509
  }
510
- return void 0;
511
510
  });
512
511
  const unsetWidth = unset ? Math.floor(remainingWidth / unset) : 0;
513
512
  return widths.map((w, i) => {
@@ -560,8 +559,7 @@ function cliui(opts, _mixin) {
560
559
  //#endregion
561
560
  //#region node_modules/.pnpm/ansi-regex@6.1.0/node_modules/ansi-regex/index.js
562
561
  function ansiRegex({ onlyFirst = false } = {}) {
563
- const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
564
- const pattern = [`[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?${ST})`, "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
562
+ const pattern = [`[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))`, "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
565
563
  return new RegExp(pattern, onlyFirst ? void 0 : "g");
566
564
  }
567
565
 
@@ -825,8 +823,7 @@ const wrapWord = (rows, word, columns) => {
825
823
  }
826
824
  if (ESCAPES.has(character)) {
827
825
  isInsideEscape = true;
828
- const ansiEscapeLinkCandidate = characters.slice(index + 1, index + 1 + ANSI_ESCAPE_LINK.length).join("");
829
- isInsideLinkEscape = ansiEscapeLinkCandidate === ANSI_ESCAPE_LINK;
826
+ isInsideLinkEscape = characters.slice(index + 1, index + 1 + ANSI_ESCAPE_LINK.length).join("") === ANSI_ESCAPE_LINK;
830
827
  }
831
828
  if (isInsideEscape) {
832
829
  if (isInsideLinkEscape) {
@@ -878,8 +875,7 @@ const exec = (string, columns, options = {}) => {
878
875
  if (options.hard && lengths[index] > columns) {
879
876
  const remainingColumns = columns - rowLength;
880
877
  const breaksStartingThisLine = 1 + Math.floor((lengths[index] - remainingColumns - 1) / columns);
881
- const breaksStartingNextLine = Math.floor((lengths[index] - 1) / columns);
882
- if (breaksStartingNextLine < breaksStartingThisLine) rows.push("");
878
+ if (Math.floor((lengths[index] - 1) / columns) < breaksStartingThisLine) rows.push("");
883
879
  wrapWord(rows, word, columns);
884
880
  continue;
885
881
  }
@@ -939,8 +935,8 @@ function ui(opts) {
939
935
  //#region node_modules/.pnpm/escalade@3.2.0/node_modules/escalade/sync/index.mjs
940
936
  function sync_default(start, callback) {
941
937
  let dir = resolve(".", start);
942
- let tmp, stats = statSync(dir);
943
- if (!stats.isDirectory()) dir = dirname(dir);
938
+ let tmp;
939
+ if (!statSync(dir).isDirectory()) dir = dirname(dir);
944
940
  while (true) {
945
941
  tmp = callback(dir, readdirSync(dir));
946
942
  if (tmp) return resolve(dir, tmp);
@@ -957,8 +953,7 @@ function sync_default(start, callback) {
957
953
  * SPDX-License-Identifier: ISC
958
954
  */
959
955
  function camelCase(str) {
960
- const isCamelCase = str !== str.toLowerCase() && str !== str.toUpperCase();
961
- if (!isCamelCase) str = str.toLowerCase();
956
+ if (!(str !== str.toLowerCase() && str !== str.toUpperCase())) str = str.toLowerCase();
962
957
  if (str.indexOf("-") === -1 && str.indexOf("_") === -1) return str;
963
958
  else {
964
959
  let camelcase = "";
@@ -1116,12 +1111,11 @@ var YargsParser = class {
1116
1111
  [].concat(opts.array || []).filter(Boolean).forEach(function(opt) {
1117
1112
  const key = typeof opt === "object" ? opt.key : opt;
1118
1113
  const assignment = Object.keys(opt).map(function(key$1) {
1119
- const arrayFlagKeys = {
1114
+ return {
1120
1115
  boolean: "bools",
1121
1116
  string: "strings",
1122
1117
  number: "numbers"
1123
- };
1124
- return arrayFlagKeys[key$1];
1118
+ }[key$1];
1125
1119
  }).filter(Boolean).pop();
1126
1120
  if (assignment) flags[assignment][key] = true;
1127
1121
  flags.arrays[key] = true;
@@ -1381,20 +1375,17 @@ var YargsParser = class {
1381
1375
  keyProperties = keyProperties.concat(a);
1382
1376
  if (!(flags.aliases[key] || []).includes(keyProperties.join("."))) setKey(argv$1, keyProperties, value);
1383
1377
  });
1384
- if (checkAllAliases(key, flags.normalize) && !checkAllAliases(key, flags.arrays)) {
1385
- const keys = [key].concat(flags.aliases[key] || []);
1386
- keys.forEach(function(key$1) {
1387
- Object.defineProperty(argvReturn, key$1, {
1388
- enumerable: true,
1389
- get() {
1390
- return val;
1391
- },
1392
- set(value$1) {
1393
- val = typeof value$1 === "string" ? mixin.normalize(value$1) : value$1;
1394
- }
1395
- });
1378
+ if (checkAllAliases(key, flags.normalize) && !checkAllAliases(key, flags.arrays)) [key].concat(flags.aliases[key] || []).forEach(function(key$1) {
1379
+ Object.defineProperty(argvReturn, key$1, {
1380
+ enumerable: true,
1381
+ get() {
1382
+ return val;
1383
+ },
1384
+ set(value$1) {
1385
+ val = typeof value$1 === "string" ? mixin.normalize(value$1) : value$1;
1386
+ }
1396
1387
  });
1397
- }
1388
+ });
1398
1389
  }
1399
1390
  function addNewAlias(key, alias) {
1400
1391
  if (!(flags.aliases[key] && flags.aliases[key].length)) {
@@ -1421,8 +1412,7 @@ var YargsParser = class {
1421
1412
  function maybeCoerceNumber(key, value) {
1422
1413
  if (!configuration["parse-positional-numbers"] && key === "_") return value;
1423
1414
  if (!checkAllAliases(key, flags.strings) && !checkAllAliases(key, flags.bools) && !Array.isArray(value)) {
1424
- const shouldCoerceNumber = looksLikeNumber(value) && configuration["parse-numbers"] && Number.isSafeInteger(Math.floor(parseFloat(`${value}`)));
1425
- if (shouldCoerceNumber || !isUndefined(value) && checkAllAliases(key, flags.numbers)) value = Number(value);
1415
+ if (looksLikeNumber(value) && configuration["parse-numbers"] && Number.isSafeInteger(Math.floor(parseFloat(`${value}`))) || !isUndefined(value) && checkAllAliases(key, flags.numbers)) value = Number(value);
1426
1416
  }
1427
1417
  return value;
1428
1418
  }
@@ -1594,14 +1584,12 @@ var YargsParser = class {
1594
1584
  }
1595
1585
  function hasAnyFlag(key) {
1596
1586
  const flagsKeys = Object.keys(flags);
1597
- const toCheck = [].concat(flagsKeys.map((k) => flags[k]));
1598
- return toCheck.some(function(flag) {
1587
+ return [].concat(flagsKeys.map((k) => flags[k])).some(function(flag) {
1599
1588
  return Array.isArray(flag) ? flag.includes(key) : flag[key];
1600
1589
  });
1601
1590
  }
1602
1591
  function hasFlagsMatching(arg, ...patterns) {
1603
- const toCheck = [].concat(...patterns);
1604
- return toCheck.some(function(pattern) {
1592
+ return [].concat(...patterns).some(function(pattern) {
1605
1593
  const match = arg.match(pattern);
1606
1594
  return match && hasAnyFlag(match[1]);
1607
1595
  });
@@ -1628,25 +1616,19 @@ var YargsParser = class {
1628
1616
  arg = arg.replace(/^-{3,}/, "--");
1629
1617
  if (arg.match(negative)) return false;
1630
1618
  if (hasAllShortFlags(arg)) return false;
1631
- const flagWithEquals = /^-+([^=]+?)=[\s\S]*$/;
1632
- const normalFlag = /^-+([^=]+?)$/;
1633
- const flagEndingInHyphen = /^-+([^=]+?)-$/;
1634
- const flagEndingInDigits = /^-+([^=]+?\d+)$/;
1635
- const flagEndingInNonWordCharacters = /^-+([^=]+?)\W+.*$/;
1636
- return !hasFlagsMatching(arg, flagWithEquals, negatedBoolean, normalFlag, flagEndingInHyphen, flagEndingInDigits, flagEndingInNonWordCharacters);
1619
+ return !hasFlagsMatching(arg, /^-+([^=]+?)=[\s\S]*$/, negatedBoolean, /^-+([^=]+?)$/, /^-+([^=]+?)-$/, /^-+([^=]+?\d+)$/, /^-+([^=]+?)\W+.*$/);
1637
1620
  }
1638
1621
  function defaultValue(key) {
1639
1622
  if (!checkAllAliases(key, flags.bools) && !checkAllAliases(key, flags.counts) && `${key}` in defaults) return defaults[key];
1640
1623
  else return defaultForType(guessType$1(key));
1641
1624
  }
1642
1625
  function defaultForType(type) {
1643
- const def = {
1626
+ return {
1644
1627
  [DefaultValuesForTypeKey.BOOLEAN]: true,
1645
1628
  [DefaultValuesForTypeKey.STRING]: "",
1646
1629
  [DefaultValuesForTypeKey.NUMBER]: void 0,
1647
1630
  [DefaultValuesForTypeKey.ARRAY]: []
1648
- };
1649
- return def[type];
1631
+ }[type];
1650
1632
  }
1651
1633
  function guessType$1(key) {
1652
1634
  let type = DefaultValuesForTypeKey.BOOLEAN;
@@ -1690,16 +1672,13 @@ function combineAliases(aliases) {
1690
1672
  });
1691
1673
  while (change) {
1692
1674
  change = false;
1693
- for (let i = 0; i < aliasArrays.length; i++) for (let ii = i + 1; ii < aliasArrays.length; ii++) {
1694
- const intersect = aliasArrays[i].filter(function(v) {
1695
- return aliasArrays[ii].indexOf(v) !== -1;
1696
- });
1697
- if (intersect.length) {
1698
- aliasArrays[i] = aliasArrays[i].concat(aliasArrays[ii]);
1699
- aliasArrays.splice(ii, 1);
1700
- change = true;
1701
- break;
1702
- }
1675
+ for (let i = 0; i < aliasArrays.length; i++) for (let ii = i + 1; ii < aliasArrays.length; ii++) if (aliasArrays[i].filter(function(v) {
1676
+ return aliasArrays[ii].indexOf(v) !== -1;
1677
+ }).length) {
1678
+ aliasArrays[i] = aliasArrays[i].concat(aliasArrays[ii]);
1679
+ aliasArrays.splice(ii, 1);
1680
+ change = true;
1681
+ break;
1703
1682
  }
1704
1683
  }
1705
1684
  aliasArrays.forEach(function(aliasArray) {
@@ -1735,8 +1714,7 @@ var _a, _b, _c;
1735
1714
  const minNodeVersion = process && process.env && process.env.YARGS_MIN_NODE_VERSION ? Number(process.env.YARGS_MIN_NODE_VERSION) : 20;
1736
1715
  const nodeVersion = (_b = (_a = process === null || process === void 0 ? void 0 : process.versions) === null || _a === void 0 ? void 0 : _a.node) !== null && _b !== void 0 ? _b : (_c = process === null || process === void 0 ? void 0 : process.version) === null || _c === void 0 ? void 0 : _c.slice(1);
1737
1716
  if (nodeVersion) {
1738
- const major = Number(nodeVersion.match(/^([^.]+)/)[1]);
1739
- if (major < minNodeVersion) throw Error(`yargs parser supports a minimum Node.js version of ${minNodeVersion}. Read our version support policy: https://github.com/yargs/yargs-parser#supported-nodejs-versions`);
1717
+ if (Number(nodeVersion.match(/^([^.]+)/)[1]) < minNodeVersion) throw Error(`yargs parser supports a minimum Node.js version of ${minNodeVersion}. Read our version support policy: https://github.com/yargs/yargs-parser#supported-nodejs-versions`);
1740
1718
  }
1741
1719
  const env = process ? process.env : {};
1742
1720
  const require$1 = createRequire ? createRequire(import.meta.url) : void 0;
@@ -1755,8 +1733,7 @@ const parser = new YargsParser({
1755
1733
  }
1756
1734
  });
1757
1735
  const yargsParser = function Parser(args, opts) {
1758
- const result = parser.parse(args.slice(), opts);
1759
- return result.argv;
1736
+ return parser.parse(args.slice(), opts).argv;
1760
1737
  };
1761
1738
  yargsParser.detailed = function(args, opts) {
1762
1739
  return parser.parse(args.slice(), opts);
@@ -1842,10 +1819,7 @@ var Y18N = class {
1842
1819
  if (typeof args[args.length - 1] === "function") cb = args.pop();
1843
1820
  if (!this.cache[this.locale]) this._readLocaleFile();
1844
1821
  let str = quantity === 1 ? singular : plural;
1845
- if (this.cache[this.locale][singular]) {
1846
- const entry = this.cache[this.locale][singular];
1847
- str = entry[quantity === 1 ? "one" : "other"];
1848
- }
1822
+ if (this.cache[this.locale][singular]) str = this.cache[this.locale][singular][quantity === 1 ? "one" : "other"];
1849
1823
  if (!this.cache[this.locale][singular] && this.updateFiles) {
1850
1824
  this.cache[this.locale][singular] = {
1851
1825
  one: singular,
@@ -2042,8 +2016,7 @@ var YError = class YError extends Error {
2042
2016
  //#endregion
2043
2017
  //#region node_modules/.pnpm/yargs@18.0.0/node_modules/yargs/build/lib/parse-command.js
2044
2018
  function parseCommand(cmd) {
2045
- const extraSpacesStrippedCommand = cmd.replace(/\s{2,}/g, " ");
2046
- const splitCommand = extraSpacesStrippedCommand.split(/\s+(?![^[]*]|[^<]*>)/);
2019
+ const splitCommand = cmd.replace(/\s{2,}/g, " ").split(/\s+(?![^[]*]|[^<]*>)/);
2047
2020
  const bregex = /\.*[\][<>]/g;
2048
2021
  const firstCommand = splitCommand.shift();
2049
2022
  if (!firstCommand) throw new Error(`No command found in: ${cmd}`);
@@ -2105,16 +2078,14 @@ function argsert(arg1, arg2, arg3) {
2105
2078
  parsed.demanded.forEach((demanded) => {
2106
2079
  const arg = args.shift();
2107
2080
  const observedType = guessType(arg);
2108
- const matchingTypes = demanded.cmd.filter((type) => type === observedType || type === "*");
2109
- if (matchingTypes.length === 0) argumentTypeError(observedType, demanded.cmd, position);
2081
+ if (demanded.cmd.filter((type) => type === observedType || type === "*").length === 0) argumentTypeError(observedType, demanded.cmd, position);
2110
2082
  position += 1;
2111
2083
  });
2112
2084
  parsed.optional.forEach((optional) => {
2113
2085
  if (args.length === 0) return;
2114
2086
  const arg = args.shift();
2115
2087
  const observedType = guessType(arg);
2116
- const matchingTypes = optional.cmd.filter((type) => type === observedType || type === "*");
2117
- if (matchingTypes.length === 0) argumentTypeError(observedType, optional.cmd, position);
2088
+ if (optional.cmd.filter((type) => type === observedType || type === "*").length === 0) argumentTypeError(observedType, optional.cmd, position);
2118
2089
  position += 1;
2119
2090
  });
2120
2091
  } catch (err) {
@@ -2264,8 +2235,7 @@ var CommandInstance = class {
2264
2235
  const joined = this.shim.path.join(fullDirPath, file);
2265
2236
  const module$1 = req(joined);
2266
2237
  const extendableModule = Object.create(null, Object.getOwnPropertyDescriptors({ ...module$1 }));
2267
- const visited = visit(extendableModule, joined, file);
2268
- if (visited) {
2238
+ if (visit(extendableModule, joined, file)) {
2269
2239
  if (this.requireCache.has(joined)) continue;
2270
2240
  else this.requireCache.add(joined);
2271
2241
  if (!extendableModule.command) extendableModule.command = this.shim.path.basename(joined, this.shim.path.extname(joined));
@@ -2526,7 +2496,6 @@ var CommandInstance = class {
2526
2496
  else if (!isCommandBuilderDefinition(builder)) Object.keys(builder).forEach((key) => {
2527
2497
  yargs.option(key, builder[key]);
2528
2498
  });
2529
- return void 0;
2530
2499
  }
2531
2500
  extractDesc({ describe, description, desc }) {
2532
2501
  for (const test of [
@@ -2835,8 +2804,7 @@ function usage(yargs, shim$2) {
2835
2804
  switches
2836
2805
  };
2837
2806
  });
2838
- const shortSwitchesUsed = displayedGroups.filter(({ groupName }) => groupName !== self.getPositionalGroupName()).some(({ normalizedKeys, switches }) => !normalizedKeys.every((key) => isLongSwitch(switches[key])));
2839
- if (shortSwitchesUsed) displayedGroups.filter(({ groupName }) => groupName !== self.getPositionalGroupName()).forEach(({ normalizedKeys, switches }) => {
2807
+ if (displayedGroups.filter(({ groupName }) => groupName !== self.getPositionalGroupName()).some(({ normalizedKeys, switches }) => !normalizedKeys.every((key) => isLongSwitch(switches[key])))) displayedGroups.filter(({ groupName }) => groupName !== self.getPositionalGroupName()).forEach(({ normalizedKeys, switches }) => {
2840
2808
  normalizedKeys.forEach((key) => {
2841
2809
  if (isLongSwitch(switches[key])) switches[key] = addIndentation(switches[key], 4);
2842
2810
  });
@@ -2974,14 +2942,12 @@ function usage(yargs, shim$2) {
2974
2942
  self.showHelp = (level) => {
2975
2943
  const logger = yargs.getInternalMethods().getLoggerInstance();
2976
2944
  if (!level) level = "error";
2977
- const emit = typeof level === "function" ? level : logger[level];
2978
- emit(self.help());
2945
+ (typeof level === "function" ? level : logger[level])(self.help());
2979
2946
  };
2980
2947
  self.functionDescription = (fn) => {
2981
- const description = fn.name ? shim$2.Parser.decamelize(fn.name, "-") : __("generated-value");
2982
2948
  return [
2983
2949
  "(",
2984
- description,
2950
+ fn.name ? shim$2.Parser.decamelize(fn.name, "-") : __("generated-value"),
2985
2951
  ")"
2986
2952
  ].join("");
2987
2953
  };
@@ -3023,8 +2989,7 @@ function usage(yargs, shim$2) {
3023
2989
  self.showVersion = (level) => {
3024
2990
  const logger = yargs.getInternalMethods().getLoggerInstance();
3025
2991
  if (!level) level = "error";
3026
- const emit = typeof level === "function" ? level : logger[level];
3027
- emit(version);
2992
+ (typeof level === "function" ? level : logger[level])(version);
3028
2993
  };
3029
2994
  self.reset = function reset(localLookup) {
3030
2995
  failMessage = null;
@@ -3195,8 +3160,7 @@ var Completion = class {
3195
3160
  const positionalKeys = this.yargs.getGroups()[this.usage.getPositionalGroupName()] || [];
3196
3161
  Object.keys(options.key).forEach((key) => {
3197
3162
  const negable = !!options.configuration["boolean-negation"] && options.boolean.includes(key);
3198
- const isPositionalKey = positionalKeys.includes(key);
3199
- if (!isPositionalKey && !options.hiddenOptions.includes(key) && !this.argsContainKey(args, key, negable)) this.completeOptionKey(key, completions, current, negable && !!options.default[key]);
3163
+ if (!positionalKeys.includes(key) && !options.hiddenOptions.includes(key) && !this.argsContainKey(args, key, negable)) this.completeOptionKey(key, completions, current, negable && !!options.default[key]);
3200
3164
  });
3201
3165
  }
3202
3166
  }
@@ -3347,8 +3311,7 @@ function validation(yargs, usage$1, shim$2) {
3347
3311
  const self = {};
3348
3312
  self.nonOptionCount = function nonOptionCount(argv$1) {
3349
3313
  const demandedCommands = yargs.getDemandedCommands();
3350
- const positionalCount = argv$1._.length + (argv$1["--"] ? argv$1["--"].length : 0);
3351
- const _s = positionalCount - yargs.getInternalMethods().getContext().commands.length;
3314
+ const _s = argv$1._.length + (argv$1["--"] ? argv$1["--"].length : 0) - yargs.getInternalMethods().getContext().commands.length;
3352
3315
  if (demandedCommands._ && (_s < demandedCommands._.min || _s > demandedCommands._.max)) {
3353
3316
  if (_s < demandedCommands._.min) if (demandedCommands._.minMsg !== void 0) usage$1.fail(demandedCommands._.minMsg ? demandedCommands._.minMsg.replace(/\$0/g, _s.toString()).replace(/\$1/, demandedCommands._.min.toString()) : null);
3354
3317
  else usage$1.fail(__n("Not enough non-option arguments: got %s, need at least %s", "Not enough non-option arguments: got %s, need at least %s", _s, _s.toString(), demandedCommands._.min.toString()));
@@ -3387,8 +3350,7 @@ function validation(yargs, usage$1, shim$2) {
3387
3350
  if (!commandKeys.includes("" + key)) unknown.push("" + key);
3388
3351
  });
3389
3352
  if (checkPositionals) {
3390
- const demandedCommands = yargs.getDemandedCommands();
3391
- const maxNonOptDemanded = ((_a$1 = demandedCommands._) === null || _a$1 === void 0 ? void 0 : _a$1.max) || 0;
3353
+ const maxNonOptDemanded = ((_a$1 = yargs.getDemandedCommands()._) === null || _a$1 === void 0 ? void 0 : _a$1.max) || 0;
3392
3354
  const expected = currentContext.commands.length + maxNonOptDemanded;
3393
3355
  if (expected < argv$1._.length) argv$1._.slice(expected).forEach((key) => {
3394
3356
  key = String(key);
@@ -4520,8 +4482,7 @@ var YargsInstance = class {
4520
4482
  this.locale(locale.replace(/[.:].*/, ""));
4521
4483
  }
4522
4484
  [kGuessVersion]() {
4523
- const obj = this[kPkgUp]();
4524
- return obj.version || "unknown";
4485
+ return this[kPkgUp]().version || "unknown";
4525
4486
  }
4526
4487
  [kParsePositionalNumbers](argv$1) {
4527
4488
  const args = argv$1["--"] ? argv$1["--"] : argv$1._;
@@ -4537,7 +4498,7 @@ var YargsInstance = class {
4537
4498
  if (__classPrivateFieldGet(this, _YargsInstance_shim, "f").path.extname(startDir)) startDir = __classPrivateFieldGet(this, _YargsInstance_shim, "f").path.dirname(startDir);
4538
4499
  const pkgJsonPath = __classPrivateFieldGet(this, _YargsInstance_shim, "f").findUp(startDir, (dir, names) => {
4539
4500
  if (names.includes("package.json")) return "package.json";
4540
- else return void 0;
4501
+ else return;
4541
4502
  });
4542
4503
  assertNotStrictEqual(pkgJsonPath, void 0, __classPrivateFieldGet(this, _YargsInstance_shim, "f"));
4543
4504
  obj = JSON.parse(__classPrivateFieldGet(this, _YargsInstance_shim, "f").readFileSync(pkgJsonPath, "utf8"));
@@ -4670,8 +4631,7 @@ var YargsInstance = class {
4670
4631
  if (calledFromCommand) return argv$1;
4671
4632
  if (isPromise(argv$1)) return argv$1;
4672
4633
  if (!populateDoubleDash) argv$1 = this[kCopyDoubleDash](argv$1);
4673
- const parsePositionalNumbers = this[kGetParserConfiguration]()["parse-positional-numbers"] || this[kGetParserConfiguration]()["parse-positional-numbers"] === void 0;
4674
- if (parsePositionalNumbers) argv$1 = this[kParsePositionalNumbers](argv$1);
4634
+ if (this[kGetParserConfiguration]()["parse-positional-numbers"] || this[kGetParserConfiguration]()["parse-positional-numbers"] === void 0) argv$1 = this[kParsePositionalNumbers](argv$1);
4675
4635
  if (runGlobalMiddleware) argv$1 = applyMiddleware(argv$1, this, __classPrivateFieldGet(this, _YargsInstance_globalMiddleware, "f").getMiddleware(), false);
4676
4636
  return argv$1;
4677
4637
  }
@@ -4766,8 +4726,7 @@ var YargsInstance = class {
4766
4726
  this[kGuessLocale]();
4767
4727
  if (shortCircuit) return this[kPostProcess](argv$1, populateDoubleDash, !!calledFromCommand, false);
4768
4728
  if (__classPrivateFieldGet(this, _YargsInstance_helpOpt, "f")) {
4769
- const helpCmds = [__classPrivateFieldGet(this, _YargsInstance_helpOpt, "f")].concat(aliases[__classPrivateFieldGet(this, _YargsInstance_helpOpt, "f")] || []).filter((k) => k.length > 1);
4770
- if (helpCmds.includes("" + argv$1._[argv$1._.length - 1])) {
4729
+ if ([__classPrivateFieldGet(this, _YargsInstance_helpOpt, "f")].concat(aliases[__classPrivateFieldGet(this, _YargsInstance_helpOpt, "f")] || []).filter((k) => k.length > 1).includes("" + argv$1._[argv$1._.length - 1])) {
4771
4730
  argv$1._.pop();
4772
4731
  helpOptSet = true;
4773
4732
  }
@@ -5057,6 +5016,10 @@ const argv = await yargs_default(hideBin(process.argv)).scriptName("mcp-proxy").
5057
5016
  describe: "The arguments to pass to the command",
5058
5017
  type: "string"
5059
5018
  }).env("MCP_PROXY").parserConfiguration({ "populate--": true }).options({
5019
+ apiKey: {
5020
+ describe: "API key for authenticating requests (uses X-API-Key header)",
5021
+ type: "string"
5022
+ },
5060
5023
  debug: {
5061
5024
  default: false,
5062
5025
  describe: "Enable debug logging",
@@ -5142,6 +5105,7 @@ const proxy = async () => {
5142
5105
  return server$1;
5143
5106
  };
5144
5107
  const server = await startHTTPServer({
5108
+ apiKey: argv.apiKey,
5145
5109
  createServer,
5146
5110
  eventStore: new InMemoryEventStore(),
5147
5111
  host: argv.host,