@alcyone-labs/arg-parser 2.6.0 → 2.7.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 +205 -26
- package/dist/core/ArgParser.d.ts +61 -0
- package/dist/core/ArgParser.d.ts.map +1 -1
- package/dist/core/ArgParserBase.d.ts +20 -0
- package/dist/core/ArgParserBase.d.ts.map +1 -1
- package/dist/index.cjs +259 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.min.mjs +3494 -3335
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.mjs +259 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -12,6 +12,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
12
12
|
var __flags, _throwForDuplicateFlags, _appName, _appCommandName, _subCommandName, _parameters, _handler, _throwForDuplicateFlags2, _description, _handleErrors, _autoExit, _parentParser, _lastParseResult, _inheritParentFlags, _subCommands, _flagManager, _dxtGenerator, _configurationManager, _fuzzyMode, _mcpResourcesManager, _mcpPromptsManager, _mcpNotificationsManager, _ArgParserBase_instances, _identifyCommandChainAndParsers_fn, _handleGlobalChecks_fn, _validateMandatoryFlags_fn, _applyDefaultValues_fn, _prepareAndExecuteHandler_fn, parseFlags_fn, _enableFuzzyMode_fn, displayErrorAndExit_fn, _printRecursiveToConsole_fn, _buildRecursiveString_fn, _buildRecursiveJson_fn, _handleSaveToEnvFlag_fn, _handleBuildDxtFlag_fn, _handleMcpServeFlag_fn, _resolveLoggerConfigForServe_fn, _getMcpServerConfiguration_fn, _startUnifiedMcpServer_fn, _findAllMcpSubCommands_fn, _parseMcpTransportOptions_fn, _ArgParser_instances, _resolveLoggerConfig_fn, registerToolAsSubCommand_fn, _startSingleTransport_fn, processAsyncHandlerPromise_fn, _hasDate, _hasTime, _offset;
|
|
13
13
|
import * as fs from "node:fs";
|
|
14
14
|
import * as path from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
15
16
|
import { createRegExp, anyOf as anyOf$1, oneOrMore, char } from "magic-regexp";
|
|
16
17
|
import { getTsconfig, createPathsMatcher } from "get-tsconfig";
|
|
17
18
|
import { z } from "zod";
|
|
@@ -3911,22 +3912,41 @@ const _ArgParserBase = class _ArgParserBase {
|
|
|
3911
3912
|
console.log("--- End Configuration Dump ---\\n");
|
|
3912
3913
|
}
|
|
3913
3914
|
}
|
|
3915
|
+
/**
|
|
3916
|
+
* Detects if the current script is being executed directly (not imported)
|
|
3917
|
+
* Uses a robust method that works across different environments and sandboxes
|
|
3918
|
+
* @param importMetaUrl The import.meta.url from the calling script (optional)
|
|
3919
|
+
* @returns true if the script is being executed directly, false if imported
|
|
3920
|
+
*/
|
|
3921
|
+
static isExecutedDirectly(importMetaUrl) {
|
|
3922
|
+
try {
|
|
3923
|
+
if (importMetaUrl) {
|
|
3924
|
+
const currentFile = fileURLToPath(importMetaUrl);
|
|
3925
|
+
const executedFile = path.resolve(process.argv[1]);
|
|
3926
|
+
return currentFile === executedFile;
|
|
3927
|
+
}
|
|
3928
|
+
if (typeof process !== "undefined" && process.argv && process.argv[1]) {
|
|
3929
|
+
return false;
|
|
3930
|
+
}
|
|
3931
|
+
return false;
|
|
3932
|
+
} catch {
|
|
3933
|
+
return false;
|
|
3934
|
+
}
|
|
3935
|
+
}
|
|
3914
3936
|
async parse(processArgs, options) {
|
|
3915
|
-
var _a
|
|
3937
|
+
var _a;
|
|
3916
3938
|
debug.log("ArgParserBase.parse() called with args:", processArgs);
|
|
3939
|
+
const shouldCheckAutoExecution = (options == null ? void 0 : options.importMetaUrl) && (options == null ? void 0 : options.autoExecute) !== false;
|
|
3940
|
+
if (shouldCheckAutoExecution) {
|
|
3941
|
+
const isDirectExecution = _ArgParserBase.isExecutedDirectly(options.importMetaUrl);
|
|
3942
|
+
if (!isDirectExecution) {
|
|
3943
|
+
debug.log("Auto-execution enabled but script is imported, skipping execution");
|
|
3944
|
+
return {};
|
|
3945
|
+
}
|
|
3946
|
+
}
|
|
3917
3947
|
if (processArgs === void 0) {
|
|
3918
3948
|
if (typeof process !== "undefined" && process.argv && Array.isArray(process.argv)) {
|
|
3919
3949
|
processArgs = process.argv.slice(2);
|
|
3920
|
-
const isCliMode = !__privateGet(this, _parentParser) && !!__privateGet(this, _appCommandName);
|
|
3921
|
-
const isMcpMode = (options == null ? void 0 : options.isMcp) || ((_a = globalThis.console) == null ? void 0 : _a.mcpError);
|
|
3922
|
-
if (isCliMode && !isMcpMode) {
|
|
3923
|
-
console.warn(
|
|
3924
|
-
`Warning: parse() called without arguments. Auto-detected Node.js environment and using process.argv.slice(2).`
|
|
3925
|
-
);
|
|
3926
|
-
console.warn(
|
|
3927
|
-
`For explicit control, call parse(process.argv.slice(2)) instead.`
|
|
3928
|
-
);
|
|
3929
|
-
}
|
|
3930
3950
|
} else {
|
|
3931
3951
|
throw new Error(
|
|
3932
3952
|
"parse() called without arguments in non-Node.js environment. Please provide arguments explicitly: parse(['--flag', 'value'])"
|
|
@@ -3951,7 +3971,7 @@ const _ArgParserBase = class _ArgParserBase {
|
|
|
3951
3971
|
commandChain: identifiedCommandChain,
|
|
3952
3972
|
parserChain: identifiedParserChain
|
|
3953
3973
|
} = __privateMethod(this, _ArgParserBase_instances, _identifyCommandChainAndParsers_fn).call(this, processArgs, this, [], [this]);
|
|
3954
|
-
const saveToEnvResult = __privateMethod(
|
|
3974
|
+
const saveToEnvResult = __privateMethod(_a = identifiedFinalParser, _ArgParserBase_instances, _handleSaveToEnvFlag_fn).call(_a, processArgs, identifiedParserChain);
|
|
3955
3975
|
if (saveToEnvResult !== false) {
|
|
3956
3976
|
return saveToEnvResult === true ? {} : saveToEnvResult;
|
|
3957
3977
|
}
|
|
@@ -5115,10 +5135,12 @@ _handleMcpServeFlag_fn = async function(processArgs, _mcpServeIndex) {
|
|
|
5115
5135
|
if (typeof loggerConfig === "string") {
|
|
5116
5136
|
mcpLogger = mcpLoggerModule.createMcpLogger("MCP Serve", loggerConfig);
|
|
5117
5137
|
} else {
|
|
5118
|
-
mcpLogger = mcpLoggerModule.createMcpLogger(
|
|
5119
|
-
loggerConfig.prefix || "MCP Serve",
|
|
5120
|
-
loggerConfig.logToFile
|
|
5121
|
-
|
|
5138
|
+
mcpLogger = mcpLoggerModule.createMcpLogger({
|
|
5139
|
+
prefix: loggerConfig.prefix || "MCP Serve",
|
|
5140
|
+
logToFile: loggerConfig.logToFile,
|
|
5141
|
+
level: loggerConfig.level,
|
|
5142
|
+
mcpMode: loggerConfig.mcpMode ?? true
|
|
5143
|
+
});
|
|
5122
5144
|
}
|
|
5123
5145
|
debug.log("Created MCP logger, about to hijack console");
|
|
5124
5146
|
globalThis.console = mcpLogger;
|
|
@@ -5270,7 +5292,10 @@ _startUnifiedMcpServer_fn = async function(mcpServerConfig, transportOptions) {
|
|
|
5270
5292
|
const finalTransportOptions = {
|
|
5271
5293
|
port: transportOptions.port,
|
|
5272
5294
|
host: transportOptions.host || "localhost",
|
|
5273
|
-
path: transportOptions.path || "/mcp"
|
|
5295
|
+
path: transportOptions.path || "/mcp",
|
|
5296
|
+
// Pass-through for streamable-http only; harmlessly ignored for others
|
|
5297
|
+
cors: transportOptions.cors,
|
|
5298
|
+
auth: transportOptions.auth
|
|
5274
5299
|
};
|
|
5275
5300
|
await mcpParser.startMcpServerWithTransport(
|
|
5276
5301
|
serverInfo,
|
|
@@ -5378,6 +5403,27 @@ _parseMcpTransportOptions_fn = function(processArgs) {
|
|
|
5378
5403
|
i++;
|
|
5379
5404
|
}
|
|
5380
5405
|
break;
|
|
5406
|
+
// Streamable HTTP extras (accept JSON string)
|
|
5407
|
+
case "--s-mcp-cors":
|
|
5408
|
+
if (nextArg && !nextArg.startsWith("-")) {
|
|
5409
|
+
try {
|
|
5410
|
+
options.cors = JSON.parse(nextArg);
|
|
5411
|
+
} catch {
|
|
5412
|
+
options.cors = nextArg;
|
|
5413
|
+
}
|
|
5414
|
+
i++;
|
|
5415
|
+
}
|
|
5416
|
+
break;
|
|
5417
|
+
case "--s-mcp-auth":
|
|
5418
|
+
if (nextArg && !nextArg.startsWith("-")) {
|
|
5419
|
+
try {
|
|
5420
|
+
options.auth = JSON.parse(nextArg);
|
|
5421
|
+
} catch {
|
|
5422
|
+
options.auth = nextArg;
|
|
5423
|
+
}
|
|
5424
|
+
i++;
|
|
5425
|
+
}
|
|
5426
|
+
break;
|
|
5381
5427
|
// Backward compatibility: support old flags but with deprecation warning
|
|
5382
5428
|
case "--transport":
|
|
5383
5429
|
case "--port":
|
|
@@ -6951,7 +6997,7 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
6951
6997
|
`After deduplication: ${uniqueTools.length} unique tools`
|
|
6952
6998
|
);
|
|
6953
6999
|
uniqueTools.forEach((tool) => {
|
|
6954
|
-
var _a2, _b2, _c2, _d, _e, _f;
|
|
7000
|
+
var _a2, _b2, _c2, _d, _e, _f, _g;
|
|
6955
7001
|
logger2.mcpError(`Registering tool: ${tool.name}`);
|
|
6956
7002
|
let zodSchema;
|
|
6957
7003
|
const toolFromUnified = Array.from(this._tools.values()).find(
|
|
@@ -7067,6 +7113,29 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7067
7113
|
inputSchema: mcpCompatibleSchema
|
|
7068
7114
|
});
|
|
7069
7115
|
}
|
|
7116
|
+
if (tool.outputSchema && this.supportsOutputSchemas()) {
|
|
7117
|
+
const convertedOutputSchema = createOutputSchema(tool.outputSchema);
|
|
7118
|
+
toolConfig.outputSchema = convertedOutputSchema;
|
|
7119
|
+
if (process.env["MCP_DEBUG"]) {
|
|
7120
|
+
console.error(
|
|
7121
|
+
`[MCP Debug] Including outputSchema for tool '${tool.name}':`,
|
|
7122
|
+
typeof tool.outputSchema
|
|
7123
|
+
);
|
|
7124
|
+
console.error(
|
|
7125
|
+
`[MCP Debug] Converted outputSchema constructor:`,
|
|
7126
|
+
(_g = convertedOutputSchema == null ? void 0 : convertedOutputSchema.constructor) == null ? void 0 : _g.name
|
|
7127
|
+
);
|
|
7128
|
+
console.error(
|
|
7129
|
+
`[MCP Debug] supportsOutputSchemas():`,
|
|
7130
|
+
this.supportsOutputSchemas()
|
|
7131
|
+
);
|
|
7132
|
+
}
|
|
7133
|
+
} else if (process.env["MCP_DEBUG"]) {
|
|
7134
|
+
console.error(
|
|
7135
|
+
`[MCP Debug] NOT including outputSchema for tool '${tool.name}':`,
|
|
7136
|
+
`hasOutputSchema=${!!tool.outputSchema}, supportsOutputSchemas=${this.supportsOutputSchemas()}`
|
|
7137
|
+
);
|
|
7138
|
+
}
|
|
7070
7139
|
const simpleExecute = async (args) => {
|
|
7071
7140
|
if (process.env["MCP_DEBUG"]) {
|
|
7072
7141
|
console.error(
|
|
@@ -7415,6 +7484,34 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7415
7484
|
parseAsync(processArgs, options) {
|
|
7416
7485
|
return this.parse(processArgs, options);
|
|
7417
7486
|
}
|
|
7487
|
+
/**
|
|
7488
|
+
* Convenience method for auto-execution: only runs if the script is executed directly (not imported).
|
|
7489
|
+
* This eliminates the need for boilerplate code to check if the script is being run directly.
|
|
7490
|
+
*
|
|
7491
|
+
* @param importMetaUrl Pass import.meta.url from your script for reliable detection
|
|
7492
|
+
* @param processArgs Optional arguments to parse (defaults to process.argv.slice(2))
|
|
7493
|
+
* @param options Additional parse options
|
|
7494
|
+
* @returns Promise that resolves to the parse result, or empty object if script is imported
|
|
7495
|
+
*
|
|
7496
|
+
* @example
|
|
7497
|
+
* ```typescript
|
|
7498
|
+
* // At the bottom of your CLI script:
|
|
7499
|
+
* await cli.parseIfExecutedDirectly(import.meta.url);
|
|
7500
|
+
*
|
|
7501
|
+
* // With error handling:
|
|
7502
|
+
* await cli.parseIfExecutedDirectly(import.meta.url).catch((error) => {
|
|
7503
|
+
* console.error("Fatal error:", error instanceof Error ? error.message : String(error));
|
|
7504
|
+
* process.exit(1);
|
|
7505
|
+
* });
|
|
7506
|
+
* ```
|
|
7507
|
+
*/
|
|
7508
|
+
async parseIfExecutedDirectly(importMetaUrl, processArgs, options) {
|
|
7509
|
+
return this.parse(processArgs, {
|
|
7510
|
+
...options,
|
|
7511
|
+
autoExecute: true,
|
|
7512
|
+
importMetaUrl
|
|
7513
|
+
});
|
|
7514
|
+
}
|
|
7418
7515
|
addMcpSubCommand(subCommandName = "mcp-server", serverInfo, optionsOrToolOptions) {
|
|
7419
7516
|
console.warn(`[DEPRECATED] addMcpSubCommand() is deprecated and will be removed in v2.0.
|
|
7420
7517
|
Please use withMcp() to configure server metadata and the --s-mcp-serve system flag instead.
|
|
@@ -7693,6 +7790,7 @@ registerToolAsSubCommand_fn = function(toolConfig) {
|
|
|
7693
7790
|
});
|
|
7694
7791
|
};
|
|
7695
7792
|
_startSingleTransport_fn = async function(server, serverInfo, transportConfig, logPath) {
|
|
7793
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7696
7794
|
const resolvedLogPath = resolveLogPath(logPath || "./logs/mcp.log");
|
|
7697
7795
|
const logger2 = createMcpLogger("MCP Transport", resolvedLogPath);
|
|
7698
7796
|
try {
|
|
@@ -7735,11 +7833,153 @@ _startSingleTransport_fn = async function(server, serverInfo, transportConfig, l
|
|
|
7735
7833
|
const { StreamableHTTPServerTransport: StreamableHTTPServerTransport2 } = await Promise.resolve().then(() => streamableHttp);
|
|
7736
7834
|
const express = (await import("express")).default;
|
|
7737
7835
|
const app = express();
|
|
7836
|
+
app.disable("x-powered-by");
|
|
7738
7837
|
app.use(express.json());
|
|
7838
|
+
app.get("/favicon.ico", (_req, res) => {
|
|
7839
|
+
const favicon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
|
7840
|
+
<rect width="16" height="16" fill="white"/>
|
|
7841
|
+
<circle cx="8" cy="8" r="4" fill="red"/>
|
|
7842
|
+
</svg>`;
|
|
7843
|
+
res.setHeader("Content-Type", "image/svg+xml");
|
|
7844
|
+
res.setHeader("Cache-Control", "public, max-age=86400");
|
|
7845
|
+
res.send(favicon);
|
|
7846
|
+
});
|
|
7847
|
+
try {
|
|
7848
|
+
(_c = (_b = (_a = this._mcpServerConfig) == null ? void 0 : _a.httpServer) == null ? void 0 : _b.configureExpress) == null ? void 0 : _c.call(_b, app);
|
|
7849
|
+
} catch (e) {
|
|
7850
|
+
}
|
|
7739
7851
|
const port = transportConfig.port || 3e3;
|
|
7740
7852
|
const path2 = transportConfig.path || "/mcp";
|
|
7853
|
+
if (transportConfig.cors) {
|
|
7854
|
+
const cors = transportConfig.cors;
|
|
7855
|
+
const allowMethods = ((_d = cors.methods) == null ? void 0 : _d.join(", ")) || "GET,POST,PUT,PATCH,DELETE,OPTIONS";
|
|
7856
|
+
const allowHeaders = (req) => {
|
|
7857
|
+
var _a2;
|
|
7858
|
+
return ((_a2 = cors.headers) == null ? void 0 : _a2.join(", ")) || req.headers["access-control-request-headers"] || "Content-Type, Authorization, MCP-Session-Id";
|
|
7859
|
+
};
|
|
7860
|
+
const exposed = ((_e = cors.exposedHeaders) == null ? void 0 : _e.join(", ")) || void 0;
|
|
7861
|
+
const resolveOrigin = (req) => {
|
|
7862
|
+
const reqOrigin = req.headers.origin;
|
|
7863
|
+
const origins = cors.origins ?? "*";
|
|
7864
|
+
if (origins === "*") return cors.credentials ? reqOrigin : "*";
|
|
7865
|
+
if (!reqOrigin) return void 0;
|
|
7866
|
+
const list = Array.isArray(origins) ? origins : [origins];
|
|
7867
|
+
for (const o of list) {
|
|
7868
|
+
if (typeof o === "string" && o === reqOrigin) return reqOrigin;
|
|
7869
|
+
if (o instanceof RegExp && o.test(reqOrigin)) return reqOrigin;
|
|
7870
|
+
}
|
|
7871
|
+
return void 0;
|
|
7872
|
+
};
|
|
7873
|
+
const applyCorsHeaders = (req, res) => {
|
|
7874
|
+
const origin = resolveOrigin(req);
|
|
7875
|
+
if (origin) res.setHeader("Access-Control-Allow-Origin", origin);
|
|
7876
|
+
if (cors.credentials) res.setHeader("Access-Control-Allow-Credentials", "true");
|
|
7877
|
+
res.setHeader("Vary", "Origin");
|
|
7878
|
+
res.setHeader("Access-Control-Allow-Methods", allowMethods);
|
|
7879
|
+
const hdrs = allowHeaders(req);
|
|
7880
|
+
if (hdrs) res.setHeader("Access-Control-Allow-Headers", hdrs);
|
|
7881
|
+
if (exposed) res.setHeader("Access-Control-Expose-Headers", exposed);
|
|
7882
|
+
if (typeof cors.maxAge === "number") res.setHeader("Access-Control-Max-Age", String(cors.maxAge));
|
|
7883
|
+
};
|
|
7884
|
+
app.options(path2, (req, res) => {
|
|
7885
|
+
applyCorsHeaders(req, res);
|
|
7886
|
+
res.status(204).end();
|
|
7887
|
+
});
|
|
7888
|
+
app.use((req, res, next) => {
|
|
7889
|
+
if (req.path === path2) applyCorsHeaders(req, res);
|
|
7890
|
+
next();
|
|
7891
|
+
});
|
|
7892
|
+
}
|
|
7893
|
+
if ((_f = transportConfig.auth) == null ? void 0 : _f.customMiddleware) {
|
|
7894
|
+
app.use(transportConfig.auth.customMiddleware);
|
|
7895
|
+
}
|
|
7896
|
+
const authOpts = transportConfig.auth;
|
|
7897
|
+
const shouldRequireAuthFor = (req) => {
|
|
7898
|
+
if (!authOpts) return false;
|
|
7899
|
+
const reqPath = req.path;
|
|
7900
|
+
const pub = authOpts.publicPaths || [];
|
|
7901
|
+
const prot = authOpts.protectedPaths;
|
|
7902
|
+
if (pub.includes(reqPath)) return false;
|
|
7903
|
+
if (prot && !prot.includes(reqPath)) return false;
|
|
7904
|
+
return authOpts.required !== false;
|
|
7905
|
+
};
|
|
7906
|
+
const base64urlDecode = (s) => Buffer.from(s.replace(/-/g, "+").replace(/_/g, "/"), "base64");
|
|
7907
|
+
const verifyJwt = async (token) => {
|
|
7908
|
+
if (!(authOpts == null ? void 0 : authOpts.jwt)) return false;
|
|
7909
|
+
const [h, p, sig] = token.split(".");
|
|
7910
|
+
if (!h || !p || !sig) return false;
|
|
7911
|
+
const header = JSON.parse(base64urlDecode(h).toString("utf8"));
|
|
7912
|
+
const payload = JSON.parse(base64urlDecode(p).toString("utf8"));
|
|
7913
|
+
const alg = header.alg;
|
|
7914
|
+
if (authOpts.jwt.algorithms && !authOpts.jwt.algorithms.includes(alg)) return false;
|
|
7915
|
+
const data2 = Buffer.from(`${h}.${p}`);
|
|
7916
|
+
const signature = base64urlDecode(sig);
|
|
7917
|
+
if (alg === "HS256") {
|
|
7918
|
+
const secret = authOpts.jwt.secret;
|
|
7919
|
+
if (!secret) return false;
|
|
7920
|
+
const hmac = (await import("node:crypto")).createHmac("sha256", secret).update(data2).digest();
|
|
7921
|
+
if (!hmac.equals(signature)) return false;
|
|
7922
|
+
} else if (alg === "RS256") {
|
|
7923
|
+
const crypto = await import("node:crypto");
|
|
7924
|
+
let key = authOpts.jwt.publicKey;
|
|
7925
|
+
if (!key && authOpts.jwt.getPublicKey) {
|
|
7926
|
+
key = await authOpts.jwt.getPublicKey(header, payload);
|
|
7927
|
+
}
|
|
7928
|
+
if (!key) return false;
|
|
7929
|
+
const verify = crypto.createVerify("RSA-SHA256");
|
|
7930
|
+
verify.update(data2);
|
|
7931
|
+
verify.end();
|
|
7932
|
+
const ok = verify.verify(key, signature);
|
|
7933
|
+
if (!ok) return false;
|
|
7934
|
+
} else {
|
|
7935
|
+
return false;
|
|
7936
|
+
}
|
|
7937
|
+
if (authOpts.jwt.audience) {
|
|
7938
|
+
const allowed = Array.isArray(authOpts.jwt.audience) ? authOpts.jwt.audience : [authOpts.jwt.audience];
|
|
7939
|
+
if (!allowed.includes(payload.aud)) return false;
|
|
7940
|
+
}
|
|
7941
|
+
if (authOpts.jwt.issuer) {
|
|
7942
|
+
const allowed = Array.isArray(authOpts.jwt.issuer) ? authOpts.jwt.issuer : [authOpts.jwt.issuer];
|
|
7943
|
+
if (!allowed.includes(payload.iss)) return false;
|
|
7944
|
+
}
|
|
7945
|
+
const nowSec = Math.floor(Date.now() / 1e3);
|
|
7946
|
+
const tol = authOpts.jwt.clockToleranceSec || 0;
|
|
7947
|
+
if (payload.nbf && nowSec + tol < payload.nbf) return false;
|
|
7948
|
+
if (payload.exp && nowSec - tol >= payload.exp) return false;
|
|
7949
|
+
return true;
|
|
7950
|
+
};
|
|
7951
|
+
const authenticate = async (req) => {
|
|
7952
|
+
if (!authOpts) return true;
|
|
7953
|
+
const authz = req.headers.authorization;
|
|
7954
|
+
const token = (authz == null ? void 0 : authz.startsWith("Bearer ")) ? authz.slice(7) : void 0;
|
|
7955
|
+
if (!token) {
|
|
7956
|
+
if (authOpts.validator) return !!await authOpts.validator(req, token);
|
|
7957
|
+
return false;
|
|
7958
|
+
}
|
|
7959
|
+
if (authOpts.scheme === "jwt" || authOpts.jwt) {
|
|
7960
|
+
const ok = await verifyJwt(token);
|
|
7961
|
+
if (!ok) return false;
|
|
7962
|
+
} else if (authOpts.scheme === "bearer" || !authOpts.scheme) {
|
|
7963
|
+
if (authOpts.allowedTokens && !authOpts.allowedTokens.includes(token)) {
|
|
7964
|
+
if (authOpts.validator) return !!await authOpts.validator(req, token);
|
|
7965
|
+
return false;
|
|
7966
|
+
}
|
|
7967
|
+
}
|
|
7968
|
+
if (authOpts.validator) {
|
|
7969
|
+
const ok = await authOpts.validator(req, token);
|
|
7970
|
+
if (!ok) return false;
|
|
7971
|
+
}
|
|
7972
|
+
return true;
|
|
7973
|
+
};
|
|
7741
7974
|
const transports = {};
|
|
7742
7975
|
app.all(path2, async (req, res) => {
|
|
7976
|
+
if (shouldRequireAuthFor(req)) {
|
|
7977
|
+
const ok = await authenticate(req);
|
|
7978
|
+
if (!ok) {
|
|
7979
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
7980
|
+
return;
|
|
7981
|
+
}
|
|
7982
|
+
}
|
|
7743
7983
|
const sessionId = req.headers["mcp-session-id"];
|
|
7744
7984
|
let transport;
|
|
7745
7985
|
if (sessionId && transports[sessionId]) {
|
|
@@ -7752,9 +7992,7 @@ _startSingleTransport_fn = async function(server, serverInfo, transportConfig, l
|
|
|
7752
7992
|
}
|
|
7753
7993
|
});
|
|
7754
7994
|
transport.onclose = () => {
|
|
7755
|
-
if (transport.sessionId)
|
|
7756
|
-
delete transports[transport.sessionId];
|
|
7757
|
-
}
|
|
7995
|
+
if (transport.sessionId) delete transports[transport.sessionId];
|
|
7758
7996
|
};
|
|
7759
7997
|
await server.connect(transport);
|
|
7760
7998
|
}
|