@ttoss/http-server-mcp 0.28.1 → 0.28.2

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 CHANGED
@@ -127,6 +127,17 @@ const data = await apiCall('GET', 'https://partner.api.com/data', {
127
127
 
128
128
  `apiCall` throws with a clear message when called with a relative path and no `apiBaseUrl` is configured in the context.
129
129
 
130
+ ### Errors
131
+
132
+ A non-2xx response throws, with the message read off the error body — `{ error: 'text' }` and `{ error: { code, message } }` both work, the latter as `code: message`. A body naming neither falls back to `HTTP <status>`.
133
+
134
+ ```typescript
135
+ // { "error": { "code": "plan_limit_reached", "message": "Upgrade to add more." } }
136
+ // → Error: plan_limit_reached: Upgrade to add more.
137
+ ```
138
+
139
+ Inside a tool handler the thrown message is what the MCP SDK returns to the client, so it is the whole answer the calling model acts on.
140
+
130
141
  ## Authentication
131
142
 
132
143
  `createMcpRouter` supports OAuth 2.0 Bearer token authentication via the `auth` option. Incoming MCP requests must include a valid `Authorization: Bearer <token>` header — invalid or missing tokens receive a `401 Unauthorized` response. The MCP lifecycle methods `initialize` and `tools/list` are exempt by default so clients can discover the server before authenticating (see [Public methods and discovery](#public-methods-and-discovery)).
@@ -593,6 +604,8 @@ Generic HTTP helper for use inside MCP tool handlers.
593
604
 
594
605
  **Returns:** `Promise<unknown>` — Parsed JSON response body
595
606
 
607
+ **Throws:** `Error` on a non-2xx response, carrying the error body's message (see [Errors](#errors))
608
+
596
609
  ### `getIdentity<T>()`
597
610
 
598
611
  Returns the verified JWT payload for the current MCP request. Only available inside a tool handler when `auth` is configured. Returns `undefined` when called outside an authenticated context.
package/dist/index.cjs CHANGED
@@ -588,6 +588,31 @@ var buildVerifyToken = auth => {
588
588
  return payload;
589
589
  };
590
590
  };
591
+ var isRecord = value => {
592
+ return typeof value === "object" && value !== null && !Array.isArray(value);
593
+ };
594
+ var readText = value => {
595
+ return typeof value === "string" && value !== "" ? value : void 0;
596
+ };
597
+ /**
598
+ * The message an error body carries, across the two shapes REST APIs answer
599
+ * with: `{ error: 'text' }` and `{ error: { code?, message? } }`.
600
+ *
601
+ * The structured one is why this is read rather than taken: an object handed
602
+ * to `new Error()` renders as `[object Object]`, and inside a tool handler
603
+ * that string is the whole answer the calling model acts on.
604
+ */
605
+ var errorBodyMessage = body => {
606
+ if (!isRecord(body)) return;
607
+ const {
608
+ error
609
+ } = body;
610
+ if (!isRecord(error)) return readText(error);
611
+ const code = readText(error.code);
612
+ const message = readText(error.message);
613
+ if (message === void 0) return code;
614
+ return code === void 0 ? message : `${code}: ${message}`;
615
+ };
591
616
  /**
592
617
  * Generic HTTP helper for use inside MCP tool handlers.
593
618
  *
@@ -663,12 +688,12 @@ var apiCall = async (method, url, options) => {
663
688
  body: hasBody ? JSON.stringify(options.body) : void 0
664
689
  });
665
690
  if (!response.ok) {
666
- const err = await response.json().catch(() => {
691
+ const errorBody = await response.json().catch(() => {
667
692
  return {
668
693
  error: response.statusText
669
694
  };
670
695
  });
671
- throw new Error(err.error || `HTTP ${response.status}`);
696
+ throw new Error(errorBodyMessage(errorBody) ?? `HTTP ${response.status}`);
672
697
  }
673
698
  if (response.status === 204 || response.status === 205) return;
674
699
  if (response.headers.get("content-type")?.includes("application/json")) return response.json();
package/dist/index.mjs CHANGED
@@ -585,6 +585,31 @@ var buildVerifyToken = auth => {
585
585
  return payload;
586
586
  };
587
587
  };
588
+ var isRecord = value => {
589
+ return typeof value === "object" && value !== null && !Array.isArray(value);
590
+ };
591
+ var readText = value => {
592
+ return typeof value === "string" && value !== "" ? value : void 0;
593
+ };
594
+ /**
595
+ * The message an error body carries, across the two shapes REST APIs answer
596
+ * with: `{ error: 'text' }` and `{ error: { code?, message? } }`.
597
+ *
598
+ * The structured one is why this is read rather than taken: an object handed
599
+ * to `new Error()` renders as `[object Object]`, and inside a tool handler
600
+ * that string is the whole answer the calling model acts on.
601
+ */
602
+ var errorBodyMessage = body => {
603
+ if (!isRecord(body)) return;
604
+ const {
605
+ error
606
+ } = body;
607
+ if (!isRecord(error)) return readText(error);
608
+ const code = readText(error.code);
609
+ const message = readText(error.message);
610
+ if (message === void 0) return code;
611
+ return code === void 0 ? message : `${code}: ${message}`;
612
+ };
588
613
  /**
589
614
  * Generic HTTP helper for use inside MCP tool handlers.
590
615
  *
@@ -660,12 +685,12 @@ var apiCall = async (method, url, options) => {
660
685
  body: hasBody ? JSON.stringify(options.body) : void 0
661
686
  });
662
687
  if (!response.ok) {
663
- const err = await response.json().catch(() => {
688
+ const errorBody = await response.json().catch(() => {
664
689
  return {
665
690
  error: response.statusText
666
691
  };
667
692
  });
668
- throw new Error(err.error || `HTTP ${response.status}`);
693
+ throw new Error(errorBodyMessage(errorBody) ?? `HTTP ${response.status}`);
669
694
  }
670
695
  if (response.status === 204 || response.status === 205) return;
671
696
  if (response.headers.get("content-type")?.includes("application/json")) return response.json();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/http-server-mcp",
3
- "version": "0.28.1",
3
+ "version": "0.28.2",
4
4
  "description": "Model Context Protocol (MCP) server integration for @ttoss/http-server",
5
5
  "keywords": [
6
6
  "ai",