@lifeaitools/clauth 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/cli/commands/serve.js +70 -5
- package/package.json +1 -1
package/cli/commands/serve.js
CHANGED
|
@@ -847,10 +847,15 @@ function dashboardHtml(port, whitelist, isStaged = false) {
|
|
|
847
847
|
<div class="mcp-setup-title">claude.ai MCP Integration</div>
|
|
848
848
|
<div class="oauth-fields">
|
|
849
849
|
<div class="mcp-row">
|
|
850
|
-
<span class="mcp-label">URL</span>
|
|
850
|
+
<span class="mcp-label">URL (all tools)</span>
|
|
851
851
|
<span class="mcp-val" id="mcp-url">—</span>
|
|
852
852
|
<button class="mcp-copy" onclick="copyMcp('mcp-url')">copy</button>
|
|
853
853
|
</div>
|
|
854
|
+
<div class="mcp-row">
|
|
855
|
+
<span class="mcp-label">URL (GWS only)</span>
|
|
856
|
+
<span class="mcp-val" id="mcp-gws-url">—</span>
|
|
857
|
+
<button class="mcp-copy" onclick="copyMcp('mcp-gws-url')">copy</button>
|
|
858
|
+
</div>
|
|
854
859
|
<div class="mcp-row">
|
|
855
860
|
<span class="mcp-label">Client ID</span>
|
|
856
861
|
<span class="mcp-val" id="mcp-client-id">—</span>
|
|
@@ -862,7 +867,10 @@ function dashboardHtml(port, whitelist, isStaged = false) {
|
|
|
862
867
|
<button class="mcp-copy" onclick="copyMcp('mcp-client-secret')">copy</button>
|
|
863
868
|
</div>
|
|
864
869
|
</div>
|
|
865
|
-
<div style="
|
|
870
|
+
<div style="display:flex;align-items:center;gap:8px;margin-top:6px">
|
|
871
|
+
<div style="font-size:.72rem;color:#64748b">Paste into <a href="https://claude.ai/settings/integrations" target="_blank" style="color:#60a5fa">claude.ai → Integrations</a></div>
|
|
872
|
+
<button class="mcp-copy" onclick="rollMcpCreds()" style="font-size:.7rem">Roll Credentials</button>
|
|
873
|
+
</div>
|
|
866
874
|
</div>
|
|
867
875
|
|
|
868
876
|
<div class="wizard-panel" id="wizard-panel">
|
|
@@ -1939,10 +1947,12 @@ async function toggleMcpSetup() {
|
|
|
1939
1947
|
try {
|
|
1940
1948
|
const m = await fetch(BASE + "/mcp-setup").then(r => r.json());
|
|
1941
1949
|
document.getElementById("mcp-url").textContent = m.url || "(tunnel not running)";
|
|
1950
|
+
document.getElementById("mcp-gws-url").textContent = m.gwsUrl || "(tunnel not running)";
|
|
1942
1951
|
document.getElementById("mcp-client-id").textContent = m.clientId || "—";
|
|
1943
1952
|
document.getElementById("mcp-client-secret").textContent = m.clientSecret || "—";
|
|
1944
1953
|
} catch {
|
|
1945
1954
|
document.getElementById("mcp-url").textContent = "(error fetching)";
|
|
1955
|
+
document.getElementById("mcp-gws-url").textContent = "(error fetching)";
|
|
1946
1956
|
}
|
|
1947
1957
|
}
|
|
1948
1958
|
}
|
|
@@ -1958,6 +1968,17 @@ function copyMcp(elId) {
|
|
|
1958
1968
|
}).catch(() => {});
|
|
1959
1969
|
}
|
|
1960
1970
|
|
|
1971
|
+
async function rollMcpCreds() {
|
|
1972
|
+
if (!confirm("Roll MCP credentials? You will need to re-add connectors in claude.ai with the new credentials.")) return;
|
|
1973
|
+
try {
|
|
1974
|
+
const resp = await fetch(BASE + "/roll-mcp-creds", { method: "POST" }).then(r => r.json());
|
|
1975
|
+
if (resp.client_id) {
|
|
1976
|
+
document.getElementById("mcp-client-id").textContent = resp.client_id;
|
|
1977
|
+
document.getElementById("mcp-client-secret").textContent = resp.client_secret;
|
|
1978
|
+
}
|
|
1979
|
+
} catch(e) { alert("Failed: " + e.message); }
|
|
1980
|
+
}
|
|
1981
|
+
|
|
1961
1982
|
// ── Tunnel Setup Wizard ─────────────────────
|
|
1962
1983
|
let wizStep = null;
|
|
1963
1984
|
let wizData = {};
|
|
@@ -2335,13 +2356,28 @@ async function wizShowMcpSetup(hostname) {
|
|
|
2335
2356
|
<div style="margin-top:10px;font-size:.78rem;color:#64748b">
|
|
2336
2357
|
Paste into <a class="wiz-link" href="https://claude.ai/settings/integrations" target="_blank">claude.ai → Settings → Integrations</a>
|
|
2337
2358
|
</div>
|
|
2359
|
+
<div style="margin-top:8px;font-size:.78rem;color:#64748b">
|
|
2360
|
+
GWS connector: use <code style="color:#60a5fa">https://\${hostname}/gws</code> as URL (same Client ID/Secret)
|
|
2361
|
+
</div>
|
|
2338
2362
|
\`, [], [
|
|
2339
2363
|
\`<button class="btn-wiz-primary" onclick="window.open('https://claude.ai/settings/integrations','_blank');wizShowTest()">I've Added It — Test Now</button>\`,
|
|
2364
|
+
\`<button class="btn-wiz-secondary" onclick="wizRollCreds()">Roll Credentials</button>\`,
|
|
2340
2365
|
\`<button class="btn-wiz-secondary" onclick="wizShowTest()">Skip Test</button>\`,
|
|
2341
2366
|
\`<button class="btn-wiz-secondary" onclick="closeSetupWizard()">Done</button>\`
|
|
2342
2367
|
]);
|
|
2343
2368
|
}
|
|
2344
2369
|
|
|
2370
|
+
async function wizRollCreds() {
|
|
2371
|
+
if (!confirm("Roll MCP credentials? Existing claude.ai connectors will need to be re-added with the new credentials.")) return;
|
|
2372
|
+
try {
|
|
2373
|
+
const resp = await apiFetch("/roll-mcp-creds", { method: "POST" });
|
|
2374
|
+
if (resp?.client_id) {
|
|
2375
|
+
document.getElementById("wiz-mcp-cid").textContent = resp.client_id;
|
|
2376
|
+
document.getElementById("wiz-mcp-sec").textContent = resp.client_secret;
|
|
2377
|
+
}
|
|
2378
|
+
} catch(e) { alert("Failed to roll credentials: " + e.message); }
|
|
2379
|
+
}
|
|
2380
|
+
|
|
2345
2381
|
function wizCopy(elId, btn) {
|
|
2346
2382
|
const val = document.getElementById(elId)?.textContent?.trim();
|
|
2347
2383
|
if (!val) return;
|
|
@@ -2531,8 +2567,8 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
|
|
|
2531
2567
|
return creds;
|
|
2532
2568
|
}
|
|
2533
2569
|
const stableCreds = loadOrCreateCreds();
|
|
2534
|
-
|
|
2535
|
-
|
|
2570
|
+
let OAUTH_CLIENT_ID = stableCreds.client_id;
|
|
2571
|
+
let OAUTH_CLIENT_SECRET = stableCreds.client_secret;
|
|
2536
2572
|
oauthClients.set(OAUTH_CLIENT_ID, {
|
|
2537
2573
|
client_id: OAUTH_CLIENT_ID, client_secret: OAUTH_CLIENT_SECRET,
|
|
2538
2574
|
client_name: "claude.ai", redirect_uris: ["https://claude.ai/api/mcp/auth_callback"],
|
|
@@ -3327,13 +3363,42 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
|
|
|
3327
3363
|
|
|
3328
3364
|
// GET /mcp-setup — OAuth credentials for claude.ai MCP setup (localhost only)
|
|
3329
3365
|
if (method === "GET" && reqPath === "/mcp-setup") {
|
|
3366
|
+
const base = tunnelUrl && tunnelUrl.startsWith("http") ? tunnelUrl : null;
|
|
3330
3367
|
return ok(res, {
|
|
3331
|
-
url:
|
|
3368
|
+
url: base ? `${base}/sse` : null,
|
|
3369
|
+
gwsUrl: base ? `${base}/gws` : null,
|
|
3332
3370
|
clientId: OAUTH_CLIENT_ID,
|
|
3333
3371
|
clientSecret: OAUTH_CLIENT_SECRET,
|
|
3334
3372
|
});
|
|
3335
3373
|
}
|
|
3336
3374
|
|
|
3375
|
+
// POST /roll-mcp-creds — generate new client ID/secret, invalidate all tokens
|
|
3376
|
+
if (method === "POST" && reqPath === "/roll-mcp-creds") {
|
|
3377
|
+
if (lockedGuard(res)) return;
|
|
3378
|
+
const newId = crypto.randomBytes(16).toString("hex");
|
|
3379
|
+
const newSecret = crypto.randomBytes(32).toString("hex");
|
|
3380
|
+
// Update in-memory
|
|
3381
|
+
oauthClients.delete(OAUTH_CLIENT_ID);
|
|
3382
|
+
OAUTH_CLIENT_ID = newId;
|
|
3383
|
+
OAUTH_CLIENT_SECRET = newSecret;
|
|
3384
|
+
stableCreds.client_id = newId;
|
|
3385
|
+
stableCreds.client_secret = newSecret;
|
|
3386
|
+
try { fs.writeFileSync(CREDS_FILE, JSON.stringify(stableCreds)); } catch {}
|
|
3387
|
+
// Register new client
|
|
3388
|
+
oauthClients.set(newId, {
|
|
3389
|
+
client_id: newId, client_secret: newSecret,
|
|
3390
|
+
client_name: "claude.ai", redirect_uris: ["https://claude.ai/api/mcp/auth_callback"],
|
|
3391
|
+
grant_types: ["authorization_code"], response_types: ["code"],
|
|
3392
|
+
token_endpoint_auth_method: "client_secret_post",
|
|
3393
|
+
});
|
|
3394
|
+
// Invalidate all existing tokens
|
|
3395
|
+
oauthTokens.clear();
|
|
3396
|
+
saveTokens(oauthTokens);
|
|
3397
|
+
const logMsg = `[${new Date().toISOString()}] OAuth: rolled credentials — new client ${newId.slice(0,8)}…, all tokens invalidated\n`;
|
|
3398
|
+
try { fs.appendFileSync(LOG_FILE, logMsg); } catch {}
|
|
3399
|
+
return ok(res, { client_id: newId, client_secret: newSecret, tokens_invalidated: true });
|
|
3400
|
+
}
|
|
3401
|
+
|
|
3337
3402
|
// POST /tunnel — start or stop tunnel manually (action in body)
|
|
3338
3403
|
if (method === "POST" && reqPath === "/tunnel") {
|
|
3339
3404
|
if (lockedGuard(res)) return;
|