llm-cli-gateway 1.5.22 → 1.5.23
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/CHANGELOG.md +8 -0
- package/dist/doctor.d.ts +1 -0
- package/dist/doctor.js +19 -0
- package/dist/http-transport.js +27 -5
- package/package.json +1 -1
- package/setup/status.schema.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the llm-cli-gateway project.
|
|
4
4
|
|
|
5
|
+
## [1.5.23] - 2026-05-25
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Add a ChatGPT-specific connector URL that uses a generated high-entropy no-auth path, while keeping the normal `/mcp` endpoint bearer-protected for clients that support Authorization headers.
|
|
10
|
+
- Make `tunnel start`, `public-url`, `print-client-config`, and the new `chatgpt-url` command report the ChatGPT URL with `Authentication: No Authentication` guidance.
|
|
11
|
+
- Teach the HTTP transport to serve explicitly configured no-auth connector paths without weakening auth on the default `/mcp` endpoint.
|
|
12
|
+
|
|
5
13
|
## [1.5.22] - 2026-05-24
|
|
6
14
|
|
|
7
15
|
### Added
|
package/dist/doctor.d.ts
CHANGED
package/dist/doctor.js
CHANGED
|
@@ -172,6 +172,24 @@ function defaultTransport(env) {
|
|
|
172
172
|
return "http";
|
|
173
173
|
return "stdio";
|
|
174
174
|
}
|
|
175
|
+
function chatGPTConnectorUrl(env, rawPublicUrl) {
|
|
176
|
+
const path = (env.LLM_GATEWAY_NO_AUTH_PATHS || "")
|
|
177
|
+
.split(/[,;\s]+/)
|
|
178
|
+
.map(value => value.trim())
|
|
179
|
+
.find(value => value.startsWith("/") && !value.includes("?") && !value.includes("#"));
|
|
180
|
+
if (!rawPublicUrl || !path)
|
|
181
|
+
return null;
|
|
182
|
+
try {
|
|
183
|
+
const url = new URL(rawPublicUrl);
|
|
184
|
+
url.pathname = path;
|
|
185
|
+
url.search = "";
|
|
186
|
+
url.hash = "";
|
|
187
|
+
return redactDiagnosticUrl(url.toString());
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
175
193
|
export function createDoctorReport(env = process.env) {
|
|
176
194
|
const auth = loadAuthConfig(env);
|
|
177
195
|
const transport = defaultTransport(env);
|
|
@@ -202,6 +220,7 @@ export function createDoctorReport(env = process.env) {
|
|
|
202
220
|
path: env.LLM_GATEWAY_HTTP_PATH || "/mcp",
|
|
203
221
|
public_url_configured: Boolean(publicUrl),
|
|
204
222
|
public_url: publicUrl,
|
|
223
|
+
chatgpt_connector_url: chatGPTConnectorUrl(env, rawPublicUrl),
|
|
205
224
|
},
|
|
206
225
|
},
|
|
207
226
|
auth: {
|
package/dist/http-transport.js
CHANGED
|
@@ -36,10 +36,26 @@ function jsonError(res, status, message) {
|
|
|
36
36
|
res.writeHead(status, { "content-type": "application/json" });
|
|
37
37
|
res.end(JSON.stringify({ error: message }));
|
|
38
38
|
}
|
|
39
|
+
function parseNoAuthPaths(raw, protectedPath) {
|
|
40
|
+
const paths = new Set();
|
|
41
|
+
for (const value of (raw ?? "").split(/[,;\s]+/)) {
|
|
42
|
+
const path = value.trim();
|
|
43
|
+
if (path &&
|
|
44
|
+
path.startsWith("/") &&
|
|
45
|
+
path !== protectedPath &&
|
|
46
|
+
!path.includes("?") &&
|
|
47
|
+
!path.includes("#") &&
|
|
48
|
+
!path.includes("..")) {
|
|
49
|
+
paths.add(path);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return paths;
|
|
53
|
+
}
|
|
39
54
|
export async function startHttpGateway(options) {
|
|
40
55
|
const host = options.host ?? process.env.LLM_GATEWAY_HTTP_HOST ?? "127.0.0.1";
|
|
41
56
|
const port = options.port ?? Number(process.env.LLM_GATEWAY_HTTP_PORT ?? 3333);
|
|
42
57
|
const path = options.path ?? process.env.LLM_GATEWAY_HTTP_PATH ?? "/mcp";
|
|
58
|
+
const noAuthPaths = parseNoAuthPaths(process.env.LLM_GATEWAY_NO_AUTH_PATHS, path);
|
|
43
59
|
const logger = options.logger ?? noopLogger;
|
|
44
60
|
const sessions = new Map();
|
|
45
61
|
const token = getRequiredBearerToken();
|
|
@@ -78,14 +94,17 @@ export async function startHttpGateway(options) {
|
|
|
78
94
|
res.end(JSON.stringify({ ok: true, sessions: sessions.size }));
|
|
79
95
|
return;
|
|
80
96
|
}
|
|
81
|
-
|
|
97
|
+
const noAuthPath = noAuthPaths.has(url.pathname);
|
|
98
|
+
if (url.pathname !== path && !noAuthPath) {
|
|
82
99
|
jsonError(res, 404, "Not found");
|
|
83
100
|
return;
|
|
84
101
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
102
|
+
if (!noAuthPath) {
|
|
103
|
+
const auth = authorizeBearerRequest(req, token);
|
|
104
|
+
if (!auth.ok) {
|
|
105
|
+
writeAuthFailure(res, auth);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
89
108
|
}
|
|
90
109
|
if (req.method !== "GET" && req.method !== "POST" && req.method !== "DELETE") {
|
|
91
110
|
methodNotAllowed(res);
|
|
@@ -150,6 +169,9 @@ export async function startHttpGateway(options) {
|
|
|
150
169
|
const actualPort = typeof address === "object" && address ? address.port : port;
|
|
151
170
|
const url = `http://${host}:${actualPort}${path}`;
|
|
152
171
|
logger.info(`HTTP MCP transport listening at ${url}`);
|
|
172
|
+
if (noAuthPaths.size > 0) {
|
|
173
|
+
logger.info(`HTTP MCP transport also serving ${noAuthPaths.size} no-auth connector path(s)`);
|
|
174
|
+
}
|
|
153
175
|
return {
|
|
154
176
|
server: httpServer,
|
|
155
177
|
url,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llm-cli-gateway",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.23",
|
|
4
4
|
"mcpName": "io.github.verivus-oss/llm-cli-gateway",
|
|
5
5
|
"description": "MCP server providing unified access to Claude Code, Codex, Gemini, Grok, and Mistral Vibe CLIs with session management, retry logic, async job orchestration, durable job results, and cross-LLM validation.",
|
|
6
6
|
"license": "MIT",
|
package/setup/status.schema.json
CHANGED
|
@@ -54,7 +54,8 @@
|
|
|
54
54
|
"port": { "type": "integer", "minimum": 1, "maximum": 65535 },
|
|
55
55
|
"path": { "type": "string" },
|
|
56
56
|
"public_url_configured": { "type": "boolean" },
|
|
57
|
-
"public_url": { "type": ["string", "null"] }
|
|
57
|
+
"public_url": { "type": ["string", "null"] },
|
|
58
|
+
"chatgpt_connector_url": { "type": ["string", "null"] }
|
|
58
59
|
},
|
|
59
60
|
"additionalProperties": false
|
|
60
61
|
}
|