@lifeaitools/clauth 1.5.12 → 1.5.14

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.
@@ -3029,41 +3029,23 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
3029
3029
  return "clauth";
3030
3030
  }
3031
3031
 
3032
- // ── MCP OAuth-protected endpoint (for claude.ai web) ──
3033
- // POST /mcp|/gws|/clauth requires Bearer token; returns 401 to trigger OAuth flow
3032
+ // ── MCP endpoint auth log all incoming POSTs, accept with or without token ──
3033
+ // /gws and /clauth are open (no OAuth gate) tunnel URL is the shared secret.
3034
+ // OAuth flow is still supported (tokens accepted when present) but not required.
3034
3035
  if (method === "POST" && isMcpPath) {
3035
3036
  const authHeader = req.headers.authorization;
3036
- // Detailed auth logging — helps diagnose claude.ai post-token failures
3037
3037
  const authLogMsg = [
3038
3038
  `[${new Date().toISOString()}] MCP POST ${reqPath}`,
3039
3039
  ` Authorization: ${authHeader ? (authHeader.startsWith("Bearer ") ? `Bearer ${authHeader.slice(7, 15)}… (known=${oauthTokens.has(authHeader.slice(7))})` : authHeader.slice(0, 30) + "…") : "(none)"}`,
3040
3040
  ` mcp-protocol-version: ${req.headers["mcp-protocol-version"] || "(not set)"}`,
3041
3041
  ` accept: ${req.headers["accept"] || "(not set)"}`,
3042
- ` x-forwarded-for: ${req.headers["x-forwarded-for"] || "(not set)"}`,
3043
3042
  ].join("\n") + "\n";
3044
3043
  try { fs.appendFileSync(LOG_FILE, authLogMsg); } catch {}
3045
-
3046
- if (!authHeader || !authHeader.startsWith("Bearer ")) {
3047
- const base = oauthBase();
3048
- // Path-specific resource metadata URL so claude.ai gets the right resource URI
3049
- const pathName = reqPath === "/mcp" ? "mcp" : reqPath.slice(1);
3050
- res.writeHead(401, {
3051
- "Content-Type": "application/json",
3052
- "WWW-Authenticate": `Bearer resource_metadata="${base}/.well-known/oauth-protected-resource/${pathName}"`,
3053
- ...CORS,
3054
- });
3055
- return res.end(JSON.stringify({ error: "unauthorized" }));
3044
+ // Mark as remote if a valid token is present (for vault access scoping)
3045
+ if (authHeader?.startsWith("Bearer ") && oauthTokens.has(authHeader.slice(7))) {
3046
+ req._clauthRemote = true;
3056
3047
  }
3057
- const token = authHeader.slice(7);
3058
- if (!oauthTokens.has(token)) {
3059
- const badTokenLog = `[${new Date().toISOString()}] OAuth: REJECTED token ${token.slice(0,8)}… (pool size=${oauthTokens.size})\n`;
3060
- try { fs.appendFileSync(LOG_FILE, badTokenLog); } catch {}
3061
- res.writeHead(401, { "Content-Type": "application/json", ...CORS });
3062
- return res.end(JSON.stringify({ error: "invalid_token" }));
3063
- }
3064
- // Token valid — mark as remote caller (claude.ai via tunnel)
3065
- req._clauthRemote = true;
3066
- // fall through to MCP handling below
3048
+ // fall through to MCP handling — no 401 gate on these paths
3067
3049
  }
3068
3050
 
3069
3051
  // ── MCP Streamable HTTP transport (2025-03-26 spec) ──
@@ -3087,12 +3069,16 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
3087
3069
  }
3088
3070
 
3089
3071
  if (rpcMethod === "initialize") {
3072
+ // Echo back the client's requested protocol version (negotiate down if needed)
3073
+ const clientVersion = req.headers["mcp-protocol-version"] || body.params?.protocolVersion || "2025-03-26";
3074
+ const SUPPORTED = ["2025-11-25", "2025-03-26"];
3075
+ const protocolVersion = SUPPORTED.includes(clientVersion) ? clientVersion : "2025-03-26";
3090
3076
  const result = {
3091
- protocolVersion: "2025-03-26",
3077
+ protocolVersion,
3092
3078
  serverInfo: { name: serverNameForPath(reqPath), version: VERSION },
3093
3079
  capabilities: { tools: {} }
3094
3080
  };
3095
- res.writeHead(200, { "Content-Type": "application/json", ...CORS });
3081
+ res.writeHead(200, { "Content-Type": "application/json", "mcp-protocol-version": protocolVersion, ...CORS });
3096
3082
  return res.end(JSON.stringify({ jsonrpc: "2.0", id, result }));
3097
3083
  }
3098
3084
 
@@ -3121,9 +3107,9 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
3121
3107
  return res.end(JSON.stringify({ jsonrpc: "2.0", id, error: { code: -32601, message: `Unknown method: ${rpcMethod}` } }));
3122
3108
  }
3123
3109
 
3124
- // ── MCP SSE transport (legacy) ───────────────────────
3125
- // GET /sse — open SSE stream, receive endpoint event
3126
- if (method === "GET" && reqPath === "/sse") {
3110
+ // ── MCP SSE transport /sse and namespaced paths ────
3111
+ // GET /sse|/gws|/clauth — open SSE stream, receive endpoint event
3112
+ if (method === "GET" && (reqPath === "/sse" || isMcpPath)) {
3127
3113
  const sessionId = `ses_${++sseCounter}_${Date.now()}`;
3128
3114
 
3129
3115
  res.writeHead(200, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/clauth",
3
- "version": "1.5.12",
3
+ "version": "1.5.14",
4
4
  "description": "Hardware-bound credential vault for the LIFEAI infrastructure stack",
5
5
  "type": "module",
6
6
  "bin": {