@ttoss/http-server-mcp 0.28.2 → 0.29.0

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
@@ -138,6 +138,20 @@ A non-2xx response throws, with the message read off the error body — `{ error
138
138
 
139
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
140
 
141
+ ### Using your own HTTP client
142
+
143
+ A handler that does not use `apiCall` can still reuse its two request-scoped pieces: `getApiHeaders()` returns the headers `getApiHeaders` produced for the current MCP request, and `errorBodyMessage(body)` renders an error body exactly as `apiCall` does.
144
+
145
+ ```typescript
146
+ import { errorBodyMessage, getApiHeaders } from '@ttoss/http-server-mcp';
147
+
148
+ const response = await fetch(url, { headers: getApiHeaders() });
149
+ if (!response.ok) {
150
+ const body = await response.json().catch(() => undefined);
151
+ throw new Error(errorBodyMessage(body) ?? `HTTP ${response.status}`);
152
+ }
153
+ ```
154
+
141
155
  ## Authentication
142
156
 
143
157
  `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)).
@@ -606,6 +620,18 @@ Generic HTTP helper for use inside MCP tool handlers.
606
620
 
607
621
  **Throws:** `Error` on a non-2xx response, carrying the error body's message (see [Errors](#errors))
608
622
 
623
+ ### `getApiHeaders()`
624
+
625
+ Returns a copy of the headers `createMcpRouter`'s `getApiHeaders` option produced for the current MCP request — the same headers `apiCall` injects.
626
+
627
+ **Returns:** `Record<string, string>` — `{}` outside a request or when `getApiHeaders` is not configured
628
+
629
+ ### `errorBodyMessage(body)`
630
+
631
+ Reads the message off a REST error body — `{ error: 'text' }` or `{ error: { code?, message? } }` (rendered `code: message`).
632
+
633
+ **Returns:** `string | undefined` — `undefined` when the body carries no message
634
+
609
635
  ### `getIdentity<T>()`
610
636
 
611
637
  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
@@ -24,6 +24,19 @@ var requestContextStore = new node_async_hooks.AsyncLocalStorage();
24
24
  var getIdentity = () => {
25
25
  return requestContextStore.getStore()?.identity;
26
26
  };
27
+ /**
28
+ * Returns the headers `getApiHeaders` produced for the current MCP request —
29
+ * the same headers `apiCall` injects. Use it inside a tool handler that runs
30
+ * its own HTTP client instead of `apiCall`, so caller credentials still reach
31
+ * the upstream API.
32
+ *
33
+ * Returns `{}` outside a request, or when `getApiHeaders` is not configured.
34
+ */
35
+ var getApiHeaders = () => {
36
+ return {
37
+ ...(requestContextStore.getStore()?.apiHeaders ?? {})
38
+ };
39
+ };
27
40
 
28
41
  //#endregion
29
42
  //#region src/serveMcpRequest.ts
@@ -601,6 +614,18 @@ var readText = value => {
601
614
  * The structured one is why this is read rather than taken: an object handed
602
615
  * to `new Error()` renders as `[object Object]`, and inside a tool handler
603
616
  * that string is the whole answer the calling model acts on.
617
+ *
618
+ * Exported so a tool handler with its own HTTP client renders error bodies
619
+ * exactly as `apiCall` does. Returns `undefined` when the body carries no
620
+ * message.
621
+ *
622
+ * @example
623
+ * ```typescript
624
+ * if (!response.ok) {
625
+ * const body = await response.json().catch(() => undefined);
626
+ * throw new Error(errorBodyMessage(body) ?? `HTTP ${response.status}`);
627
+ * }
628
+ * ```
604
629
  */
605
630
  var errorBodyMessage = body => {
606
631
  if (!isRecord(body)) return;
@@ -885,6 +910,8 @@ exports.apiCall = apiCall;
885
910
  exports.checkScopes = checkScopes;
886
911
  exports.createGatedToolRegistrar = createGatedToolRegistrar;
887
912
  exports.createMcpRouter = createMcpRouter;
913
+ exports.errorBodyMessage = errorBodyMessage;
914
+ exports.getApiHeaders = getApiHeaders;
888
915
  exports.getIdentity = getIdentity;
889
916
  exports.registerAppResource = registerAppResource;
890
917
  exports.registerToolFromSchema = registerToolFromSchema;
package/dist/index.d.cts CHANGED
@@ -674,6 +674,15 @@ declare namespace Application {
674
674
  * Omitting the type parameter keeps the return type as `unknown | undefined`.
675
675
  */
676
676
  declare const getIdentity: <T = unknown>() => T | undefined;
677
+ /**
678
+ * Returns the headers `getApiHeaders` produced for the current MCP request —
679
+ * the same headers `apiCall` injects. Use it inside a tool handler that runs
680
+ * its own HTTP client instead of `apiCall`, so caller credentials still reach
681
+ * the upstream API.
682
+ *
683
+ * Returns `{}` outside a request, or when `getApiHeaders` is not configured.
684
+ */
685
+ declare const getApiHeaders: () => Record<string, string>;
677
686
  //#endregion
678
687
  //#region src/registerAppResource.d.ts
679
688
  /**
@@ -1191,6 +1200,27 @@ interface McpAuthOptions {
1191
1200
  */
1192
1201
  resourceIndicator?: string | string[];
1193
1202
  }
1203
+ /**
1204
+ * The message an error body carries, across the two shapes REST APIs answer
1205
+ * with: `{ error: 'text' }` and `{ error: { code?, message? } }`.
1206
+ *
1207
+ * The structured one is why this is read rather than taken: an object handed
1208
+ * to `new Error()` renders as `[object Object]`, and inside a tool handler
1209
+ * that string is the whole answer the calling model acts on.
1210
+ *
1211
+ * Exported so a tool handler with its own HTTP client renders error bodies
1212
+ * exactly as `apiCall` does. Returns `undefined` when the body carries no
1213
+ * message.
1214
+ *
1215
+ * @example
1216
+ * ```typescript
1217
+ * if (!response.ok) {
1218
+ * const body = await response.json().catch(() => undefined);
1219
+ * throw new Error(errorBodyMessage(body) ?? `HTTP ${response.status}`);
1220
+ * }
1221
+ * ```
1222
+ */
1223
+ declare const errorBodyMessage: (body: unknown) => string | undefined;
1194
1224
  /**
1195
1225
  * Options for a single `apiCall` request.
1196
1226
  */
@@ -1444,4 +1474,4 @@ interface McpRouterOptions {
1444
1474
  */
1445
1475
  declare const createMcpRouter: (server: McpServer$1, options?: McpRouterOptions) => Router<Application.DefaultState, Application.DefaultContext>;
1446
1476
  //#endregion
1447
- export { ApiCallOptions, CognitoUserPoolConfig, type CreateGatedToolRegistrarOptions, type GatedToolDef, type JsonObjectSchema, McpAuthOptions, McpRouterOptions, McpServer, type RegisterAppResourceParams, type RegisterToolFromSchemaParams, type RegisteredAppResource, type ToolCallContext, type ToolIdentity, type ToolMetaParams, UI_EXTENSION_ID, UI_RESOURCE_MIME_TYPE, type UiResourceCsp, type UiResourceMeta, type UiResourcePermissions, type UiToolVisibility, apiCall, checkScopes, createGatedToolRegistrar, createMcpRouter, getIdentity, registerAppResource, registerToolFromSchema, z };
1477
+ export { ApiCallOptions, CognitoUserPoolConfig, type CreateGatedToolRegistrarOptions, type GatedToolDef, type JsonObjectSchema, McpAuthOptions, McpRouterOptions, McpServer, type RegisterAppResourceParams, type RegisterToolFromSchemaParams, type RegisteredAppResource, type ToolCallContext, type ToolIdentity, type ToolMetaParams, UI_EXTENSION_ID, UI_RESOURCE_MIME_TYPE, type UiResourceCsp, type UiResourceMeta, type UiResourcePermissions, type UiToolVisibility, apiCall, checkScopes, createGatedToolRegistrar, createMcpRouter, errorBodyMessage, getApiHeaders, getIdentity, registerAppResource, registerToolFromSchema, z };
package/dist/index.d.mts CHANGED
@@ -675,6 +675,15 @@ declare namespace Application {
675
675
  * Omitting the type parameter keeps the return type as `unknown | undefined`.
676
676
  */
677
677
  declare const getIdentity: <T = unknown>() => T | undefined;
678
+ /**
679
+ * Returns the headers `getApiHeaders` produced for the current MCP request —
680
+ * the same headers `apiCall` injects. Use it inside a tool handler that runs
681
+ * its own HTTP client instead of `apiCall`, so caller credentials still reach
682
+ * the upstream API.
683
+ *
684
+ * Returns `{}` outside a request, or when `getApiHeaders` is not configured.
685
+ */
686
+ declare const getApiHeaders: () => Record<string, string>;
678
687
  //#endregion
679
688
  //#region src/registerAppResource.d.ts
680
689
  /**
@@ -1192,6 +1201,27 @@ interface McpAuthOptions {
1192
1201
  */
1193
1202
  resourceIndicator?: string | string[];
1194
1203
  }
1204
+ /**
1205
+ * The message an error body carries, across the two shapes REST APIs answer
1206
+ * with: `{ error: 'text' }` and `{ error: { code?, message? } }`.
1207
+ *
1208
+ * The structured one is why this is read rather than taken: an object handed
1209
+ * to `new Error()` renders as `[object Object]`, and inside a tool handler
1210
+ * that string is the whole answer the calling model acts on.
1211
+ *
1212
+ * Exported so a tool handler with its own HTTP client renders error bodies
1213
+ * exactly as `apiCall` does. Returns `undefined` when the body carries no
1214
+ * message.
1215
+ *
1216
+ * @example
1217
+ * ```typescript
1218
+ * if (!response.ok) {
1219
+ * const body = await response.json().catch(() => undefined);
1220
+ * throw new Error(errorBodyMessage(body) ?? `HTTP ${response.status}`);
1221
+ * }
1222
+ * ```
1223
+ */
1224
+ declare const errorBodyMessage: (body: unknown) => string | undefined;
1195
1225
  /**
1196
1226
  * Options for a single `apiCall` request.
1197
1227
  */
@@ -1445,4 +1475,4 @@ interface McpRouterOptions {
1445
1475
  */
1446
1476
  declare const createMcpRouter: (server: McpServer$1, options?: McpRouterOptions) => Router<Application.DefaultState, Application.DefaultContext>;
1447
1477
  //#endregion
1448
- export { ApiCallOptions, CognitoUserPoolConfig, type CreateGatedToolRegistrarOptions, type GatedToolDef, type JsonObjectSchema, McpAuthOptions, McpRouterOptions, McpServer, type RegisterAppResourceParams, type RegisterToolFromSchemaParams, type RegisteredAppResource, type ToolCallContext, type ToolIdentity, type ToolMetaParams, UI_EXTENSION_ID, UI_RESOURCE_MIME_TYPE, type UiResourceCsp, type UiResourceMeta, type UiResourcePermissions, type UiToolVisibility, apiCall, checkScopes, createGatedToolRegistrar, createMcpRouter, getIdentity, registerAppResource, registerToolFromSchema, z };
1478
+ export { ApiCallOptions, CognitoUserPoolConfig, type CreateGatedToolRegistrarOptions, type GatedToolDef, type JsonObjectSchema, McpAuthOptions, McpRouterOptions, McpServer, type RegisterAppResourceParams, type RegisterToolFromSchemaParams, type RegisteredAppResource, type ToolCallContext, type ToolIdentity, type ToolMetaParams, UI_EXTENSION_ID, UI_RESOURCE_MIME_TYPE, type UiResourceCsp, type UiResourceMeta, type UiResourcePermissions, type UiToolVisibility, apiCall, checkScopes, createGatedToolRegistrar, createMcpRouter, errorBodyMessage, getApiHeaders, getIdentity, registerAppResource, registerToolFromSchema, z };
package/dist/index.mjs CHANGED
@@ -21,6 +21,19 @@ var requestContextStore = new AsyncLocalStorage();
21
21
  var getIdentity = () => {
22
22
  return requestContextStore.getStore()?.identity;
23
23
  };
24
+ /**
25
+ * Returns the headers `getApiHeaders` produced for the current MCP request —
26
+ * the same headers `apiCall` injects. Use it inside a tool handler that runs
27
+ * its own HTTP client instead of `apiCall`, so caller credentials still reach
28
+ * the upstream API.
29
+ *
30
+ * Returns `{}` outside a request, or when `getApiHeaders` is not configured.
31
+ */
32
+ var getApiHeaders = () => {
33
+ return {
34
+ ...(requestContextStore.getStore()?.apiHeaders ?? {})
35
+ };
36
+ };
24
37
 
25
38
  //#endregion
26
39
  //#region src/serveMcpRequest.ts
@@ -598,6 +611,18 @@ var readText = value => {
598
611
  * The structured one is why this is read rather than taken: an object handed
599
612
  * to `new Error()` renders as `[object Object]`, and inside a tool handler
600
613
  * that string is the whole answer the calling model acts on.
614
+ *
615
+ * Exported so a tool handler with its own HTTP client renders error bodies
616
+ * exactly as `apiCall` does. Returns `undefined` when the body carries no
617
+ * message.
618
+ *
619
+ * @example
620
+ * ```typescript
621
+ * if (!response.ok) {
622
+ * const body = await response.json().catch(() => undefined);
623
+ * throw new Error(errorBodyMessage(body) ?? `HTTP ${response.status}`);
624
+ * }
625
+ * ```
601
626
  */
602
627
  var errorBodyMessage = body => {
603
628
  if (!isRecord(body)) return;
@@ -870,4 +895,4 @@ var createMcpRouter = (server, options = {}) => {
870
895
  };
871
896
 
872
897
  //#endregion
873
- export { McpServer, UI_EXTENSION_ID, UI_RESOURCE_MIME_TYPE, apiCall, checkScopes, createGatedToolRegistrar, createMcpRouter, getIdentity, registerAppResource, registerToolFromSchema, z };
898
+ export { McpServer, UI_EXTENSION_ID, UI_RESOURCE_MIME_TYPE, apiCall, checkScopes, createGatedToolRegistrar, createMcpRouter, errorBodyMessage, getApiHeaders, getIdentity, registerAppResource, registerToolFromSchema, z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/http-server-mcp",
3
- "version": "0.28.2",
3
+ "version": "0.29.0",
4
4
  "description": "Model Context Protocol (MCP) server integration for @ttoss/http-server",
5
5
  "keywords": [
6
6
  "ai",