rhombus-node-mcp 0.1.35 → 0.1.36

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.
@@ -2,15 +2,18 @@ import { logger } from "../logger.js";
2
2
  import { postApi } from "../network/network.js";
3
3
  /**
4
4
  * Fetches `user.accessibleRhombusApps` from getCurrentUser for the given session.
5
- * Result is cached in-memory for the lifetime of the session. Returns null on
6
- * error or missing session; callers should fall back to a permissive default.
5
+ * Successful results are cached in-memory for the lifetime of the session;
6
+ * failures are NOT cached so transient errors don't poison the session.
7
+ * Returns null on error or missing session; callers should fall back to a
8
+ * permissive default.
7
9
  */
8
10
  const cache = new Map();
9
11
  export async function resolveAccessibleApps(sessionId) {
10
12
  if (!sessionId)
11
13
  return null;
12
- if (cache.has(sessionId))
13
- return cache.get(sessionId) ?? null;
14
+ const cached = cache.get(sessionId);
15
+ if (cached !== undefined)
16
+ return cached;
14
17
  try {
15
18
  const res = await postApi({
16
19
  route: "/customer/getCurrentUser",
@@ -19,7 +22,6 @@ export async function resolveAccessibleApps(sessionId) {
19
22
  });
20
23
  if (res.error) {
21
24
  logger.warn(`resolveAccessibleApps: getCurrentUser failed for session ${sessionId}`);
22
- cache.set(sessionId, null);
23
25
  return null;
24
26
  }
25
27
  const apps = (res.user?.accessibleRhombusApps ?? []).filter((a) => a !== null && a !== undefined);
@@ -29,7 +31,6 @@ export async function resolveAccessibleApps(sessionId) {
29
31
  }
30
32
  catch (e) {
31
33
  logger.warn(`resolveAccessibleApps: error for session ${sessionId}: ${String(e)}`);
32
- cache.set(sessionId, null);
33
34
  return null;
34
35
  }
35
36
  }
@@ -75,7 +75,6 @@ export default function streamableHttpTransport() {
75
75
  /**
76
76
  * STATEFUL ENDPOINT
77
77
  */
78
- const authRequired = ["tools/call"];
79
78
  app.post("/mcp", async (req, res) => {
80
79
  logger.info(`Received MCP request`, JSON.stringify(req.body, null, 2));
81
80
  // Check for existing session ID
@@ -95,8 +94,13 @@ export default function streamableHttpTransport() {
95
94
  // onsessioninitialized.
96
95
  const newSessionId = crypto.randomUUID();
97
96
  const authOk = populateAuthStore(req, newSessionId);
98
- if (!authOk && authRequired.includes(req.body.method)) {
99
- logger.error(`Auth required for ${req.body.method} but auth could not be populated`);
97
+ // Reject the initialize itself when auth couldn't be populated. Letting
98
+ // the session through without an authStore entry only defers the failure:
99
+ // any later /customer/getCurrentUser (during tool registration) or tool
100
+ // call will throw "No auth found for sessionId" from network.ts, which
101
+ // is harder to diagnose than an upfront 401 here.
102
+ if (!authOk) {
103
+ logger.error(`Auth could not be populated for ${req.body.method}; rejecting`);
100
104
  res
101
105
  .status(401)
102
106
  .setHeader("WWW-Authenticate", `Bearer realm="${process.env.REALM}", error="invalid_token", error_description="The access token is missing or invalid"`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rhombus-node-mcp",
3
- "version": "0.1.35",
3
+ "version": "0.1.36",
4
4
  "description": "MCP server for Rhombus API",
5
5
  "keywords": [
6
6
  "ai",