@henrylabs/mcp 0.15.0 → 0.18.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.
Files changed (197) hide show
  1. package/README.md +13 -334
  2. package/code-tool.d.mts +2 -44
  3. package/code-tool.d.mts.map +1 -1
  4. package/code-tool.d.ts +2 -44
  5. package/code-tool.d.ts.map +1 -1
  6. package/code-tool.js +7 -3
  7. package/code-tool.js.map +1 -1
  8. package/code-tool.mjs +7 -3
  9. package/code-tool.mjs.map +1 -1
  10. package/docs-search-tool.d.mts +3 -3
  11. package/docs-search-tool.d.mts.map +1 -1
  12. package/docs-search-tool.d.ts +3 -3
  13. package/docs-search-tool.d.ts.map +1 -1
  14. package/docs-search-tool.js +1 -1
  15. package/docs-search-tool.js.map +1 -1
  16. package/docs-search-tool.mjs +1 -1
  17. package/http.d.mts.map +1 -1
  18. package/http.d.ts.map +1 -1
  19. package/http.js +1 -18
  20. package/http.js.map +1 -1
  21. package/http.mjs +1 -18
  22. package/http.mjs.map +1 -1
  23. package/index.js +4 -40
  24. package/index.js.map +1 -1
  25. package/index.mjs +4 -40
  26. package/index.mjs.map +1 -1
  27. package/options.d.mts +0 -9
  28. package/options.d.mts.map +1 -1
  29. package/options.d.ts +0 -9
  30. package/options.d.ts.map +1 -1
  31. package/options.js +4 -359
  32. package/options.js.map +1 -1
  33. package/options.mjs +4 -359
  34. package/options.mjs.map +1 -1
  35. package/package.json +9 -49
  36. package/server.d.mts +3 -8
  37. package/server.d.mts.map +1 -1
  38. package/server.d.ts +3 -8
  39. package/server.d.ts.map +1 -1
  40. package/server.js +12 -65
  41. package/server.js.map +1 -1
  42. package/server.mjs +11 -62
  43. package/server.mjs.map +1 -1
  44. package/src/code-tool.ts +7 -3
  45. package/src/docs-search-tool.ts +1 -1
  46. package/src/http.ts +1 -19
  47. package/src/index.ts +5 -52
  48. package/src/options.ts +5 -386
  49. package/src/server.ts +12 -72
  50. package/src/stdio.ts +2 -3
  51. package/src/{tools/types.ts → types.ts} +1 -1
  52. package/stdio.d.mts +1 -2
  53. package/stdio.d.mts.map +1 -1
  54. package/stdio.d.ts +1 -2
  55. package/stdio.d.ts.map +1 -1
  56. package/stdio.js +2 -2
  57. package/stdio.js.map +1 -1
  58. package/stdio.mjs +2 -2
  59. package/stdio.mjs.map +1 -1
  60. package/{tools/types.d.mts → types.d.mts} +1 -1
  61. package/types.d.mts.map +1 -0
  62. package/{tools/types.d.ts → types.d.ts} +1 -1
  63. package/types.d.ts.map +1 -0
  64. package/types.js.map +1 -0
  65. package/types.mjs.map +1 -0
  66. package/compat.d.mts +0 -58
  67. package/compat.d.mts.map +0 -1
  68. package/compat.d.ts +0 -58
  69. package/compat.d.ts.map +0 -1
  70. package/compat.js +0 -387
  71. package/compat.js.map +0 -1
  72. package/compat.mjs +0 -378
  73. package/compat.mjs.map +0 -1
  74. package/dynamic-tools.d.mts +0 -12
  75. package/dynamic-tools.d.mts.map +0 -1
  76. package/dynamic-tools.d.ts +0 -12
  77. package/dynamic-tools.d.ts.map +0 -1
  78. package/dynamic-tools.js +0 -135
  79. package/dynamic-tools.js.map +0 -1
  80. package/dynamic-tools.mjs +0 -132
  81. package/dynamic-tools.mjs.map +0 -1
  82. package/filtering.d.mts +0 -3
  83. package/filtering.d.mts.map +0 -1
  84. package/filtering.d.ts +0 -3
  85. package/filtering.d.ts.map +0 -1
  86. package/filtering.js +0 -24
  87. package/filtering.js.map +0 -1
  88. package/filtering.mjs +0 -16
  89. package/filtering.mjs.map +0 -1
  90. package/src/compat.ts +0 -483
  91. package/src/dynamic-tools.ts +0 -153
  92. package/src/filtering.ts +0 -18
  93. package/src/tools/cart/create-cart-checkout.ts +0 -60
  94. package/src/tools/cart/items/add-cart-items.ts +0 -100
  95. package/src/tools/cart/items/clear-cart-items.ts +0 -54
  96. package/src/tools/cart/items/list-cart-items.ts +0 -54
  97. package/src/tools/cart/items/remove-cart-items.ts +0 -57
  98. package/src/tools/index.ts +0 -87
  99. package/src/tools/orders/retrieve-status-orders.ts +0 -54
  100. package/src/tools/products/retrieve-product-details.ts +0 -48
  101. package/src/tools/products/search-products.ts +0 -110
  102. package/src/tools/wallet/collect-payment-details.ts +0 -56
  103. package/src/tools.ts +0 -1
  104. package/tools/cart/create-cart-checkout.d.mts +0 -51
  105. package/tools/cart/create-cart-checkout.d.mts.map +0 -1
  106. package/tools/cart/create-cart-checkout.d.ts +0 -51
  107. package/tools/cart/create-cart-checkout.d.ts.map +0 -1
  108. package/tools/cart/create-cart-checkout.js +0 -60
  109. package/tools/cart/create-cart-checkout.js.map +0 -1
  110. package/tools/cart/create-cart-checkout.mjs +0 -53
  111. package/tools/cart/create-cart-checkout.mjs.map +0 -1
  112. package/tools/cart/items/add-cart-items.d.mts +0 -51
  113. package/tools/cart/items/add-cart-items.d.mts.map +0 -1
  114. package/tools/cart/items/add-cart-items.d.ts +0 -51
  115. package/tools/cart/items/add-cart-items.d.ts.map +0 -1
  116. package/tools/cart/items/add-cart-items.js +0 -98
  117. package/tools/cart/items/add-cart-items.js.map +0 -1
  118. package/tools/cart/items/add-cart-items.mjs +0 -91
  119. package/tools/cart/items/add-cart-items.mjs.map +0 -1
  120. package/tools/cart/items/clear-cart-items.d.mts +0 -51
  121. package/tools/cart/items/clear-cart-items.d.mts.map +0 -1
  122. package/tools/cart/items/clear-cart-items.d.ts +0 -51
  123. package/tools/cart/items/clear-cart-items.d.ts.map +0 -1
  124. package/tools/cart/items/clear-cart-items.js +0 -54
  125. package/tools/cart/items/clear-cart-items.js.map +0 -1
  126. package/tools/cart/items/clear-cart-items.mjs +0 -47
  127. package/tools/cart/items/clear-cart-items.mjs.map +0 -1
  128. package/tools/cart/items/list-cart-items.d.mts +0 -51
  129. package/tools/cart/items/list-cart-items.d.mts.map +0 -1
  130. package/tools/cart/items/list-cart-items.d.ts +0 -51
  131. package/tools/cart/items/list-cart-items.d.ts.map +0 -1
  132. package/tools/cart/items/list-cart-items.js +0 -54
  133. package/tools/cart/items/list-cart-items.js.map +0 -1
  134. package/tools/cart/items/list-cart-items.mjs +0 -47
  135. package/tools/cart/items/list-cart-items.mjs.map +0 -1
  136. package/tools/cart/items/remove-cart-items.d.mts +0 -51
  137. package/tools/cart/items/remove-cart-items.d.mts.map +0 -1
  138. package/tools/cart/items/remove-cart-items.d.ts +0 -51
  139. package/tools/cart/items/remove-cart-items.d.ts.map +0 -1
  140. package/tools/cart/items/remove-cart-items.js +0 -57
  141. package/tools/cart/items/remove-cart-items.js.map +0 -1
  142. package/tools/cart/items/remove-cart-items.mjs +0 -50
  143. package/tools/cart/items/remove-cart-items.mjs.map +0 -1
  144. package/tools/index.d.mts +0 -10
  145. package/tools/index.d.mts.map +0 -1
  146. package/tools/index.d.ts +0 -10
  147. package/tools/index.d.ts.map +0 -1
  148. package/tools/index.js +0 -71
  149. package/tools/index.js.map +0 -1
  150. package/tools/index.mjs +0 -64
  151. package/tools/index.mjs.map +0 -1
  152. package/tools/orders/retrieve-status-orders.d.mts +0 -51
  153. package/tools/orders/retrieve-status-orders.d.mts.map +0 -1
  154. package/tools/orders/retrieve-status-orders.d.ts +0 -51
  155. package/tools/orders/retrieve-status-orders.d.ts.map +0 -1
  156. package/tools/orders/retrieve-status-orders.js +0 -54
  157. package/tools/orders/retrieve-status-orders.js.map +0 -1
  158. package/tools/orders/retrieve-status-orders.mjs +0 -47
  159. package/tools/orders/retrieve-status-orders.mjs.map +0 -1
  160. package/tools/products/retrieve-product-details.d.mts +0 -51
  161. package/tools/products/retrieve-product-details.d.mts.map +0 -1
  162. package/tools/products/retrieve-product-details.d.ts +0 -51
  163. package/tools/products/retrieve-product-details.d.ts.map +0 -1
  164. package/tools/products/retrieve-product-details.js +0 -49
  165. package/tools/products/retrieve-product-details.js.map +0 -1
  166. package/tools/products/retrieve-product-details.mjs +0 -42
  167. package/tools/products/retrieve-product-details.mjs.map +0 -1
  168. package/tools/products/search-products.d.mts +0 -51
  169. package/tools/products/search-products.d.mts.map +0 -1
  170. package/tools/products/search-products.d.ts +0 -51
  171. package/tools/products/search-products.d.ts.map +0 -1
  172. package/tools/products/search-products.js +0 -110
  173. package/tools/products/search-products.js.map +0 -1
  174. package/tools/products/search-products.mjs +0 -103
  175. package/tools/products/search-products.mjs.map +0 -1
  176. package/tools/types.d.mts.map +0 -1
  177. package/tools/types.d.ts.map +0 -1
  178. package/tools/types.js.map +0 -1
  179. package/tools/types.mjs.map +0 -1
  180. package/tools/wallet/collect-payment-details.d.mts +0 -51
  181. package/tools/wallet/collect-payment-details.d.mts.map +0 -1
  182. package/tools/wallet/collect-payment-details.d.ts +0 -51
  183. package/tools/wallet/collect-payment-details.d.ts.map +0 -1
  184. package/tools/wallet/collect-payment-details.js +0 -56
  185. package/tools/wallet/collect-payment-details.js.map +0 -1
  186. package/tools/wallet/collect-payment-details.mjs +0 -49
  187. package/tools/wallet/collect-payment-details.mjs.map +0 -1
  188. package/tools.d.mts +0 -2
  189. package/tools.d.mts.map +0 -1
  190. package/tools.d.ts +0 -2
  191. package/tools.d.ts.map +0 -1
  192. package/tools.js +0 -18
  193. package/tools.js.map +0 -1
  194. package/tools.mjs +0 -2
  195. package/tools.mjs.map +0 -1
  196. /package/{tools/types.js → types.js} +0 -0
  197. /package/{tools/types.mjs → types.mjs} +0 -0
@@ -1,153 +0,0 @@
1
- import HenrySDK from '@henrylabs/sdk';
2
- import { Endpoint, asTextContentResult, ToolCallResult } from './tools/types';
3
- import { zodToJsonSchema } from 'zod-to-json-schema';
4
- import { z } from 'zod';
5
- import { Cabidela } from '@cloudflare/cabidela';
6
-
7
- function zodToInputSchema(schema: z.ZodSchema) {
8
- return {
9
- type: 'object' as const,
10
- ...(zodToJsonSchema(schema) as any),
11
- };
12
- }
13
-
14
- /**
15
- * A list of tools that expose all the endpoints in the API dynamically.
16
- *
17
- * Instead of exposing every endpoint as its own tool, which uses up too many tokens for LLMs to use at once,
18
- * we expose a single tool that can be used to search for endpoints by name, resource, operation, or tag, and then
19
- * a generic endpoint that can be used to invoke any endpoint with the provided arguments.
20
- *
21
- * @param endpoints - The endpoints to include in the list.
22
- */
23
- export function dynamicTools(endpoints: Endpoint[]): Endpoint[] {
24
- const listEndpointsSchema = z.object({
25
- search_query: z
26
- .string()
27
- .optional()
28
- .describe(
29
- 'An optional search query to filter the endpoints by. Provide a partial name, resource, operation, or tag to filter the endpoints returned.',
30
- ),
31
- });
32
-
33
- const listEndpointsTool = {
34
- metadata: {
35
- resource: 'dynamic_tools',
36
- operation: 'read' as const,
37
- tags: [],
38
- },
39
- tool: {
40
- name: 'list_api_endpoints',
41
- description: 'List or search for all endpoints in the Henry SDK TypeScript API',
42
- inputSchema: zodToInputSchema(listEndpointsSchema),
43
- },
44
- handler: async (client: HenrySDK, args: Record<string, unknown> | undefined): Promise<ToolCallResult> => {
45
- const query = args && listEndpointsSchema.parse(args).search_query?.trim();
46
-
47
- const filteredEndpoints =
48
- query && query.length > 0 ?
49
- endpoints.filter((endpoint) => {
50
- const fieldsToMatch = [
51
- endpoint.tool.name,
52
- endpoint.tool.description,
53
- endpoint.metadata.resource,
54
- endpoint.metadata.operation,
55
- ...endpoint.metadata.tags,
56
- ];
57
- return fieldsToMatch.some((field) => field && field.toLowerCase().includes(query.toLowerCase()));
58
- })
59
- : endpoints;
60
-
61
- return asTextContentResult({
62
- tools: filteredEndpoints.map(({ tool, metadata }) => ({
63
- name: tool.name,
64
- description: tool.description,
65
- resource: metadata.resource,
66
- operation: metadata.operation,
67
- tags: metadata.tags,
68
- })),
69
- });
70
- },
71
- };
72
-
73
- const getEndpointSchema = z.object({
74
- endpoint: z.string().describe('The name of the endpoint to get the schema for.'),
75
- });
76
- const getEndpointTool = {
77
- metadata: {
78
- resource: 'dynamic_tools',
79
- operation: 'read' as const,
80
- tags: [],
81
- },
82
- tool: {
83
- name: 'get_api_endpoint_schema',
84
- description:
85
- 'Get the schema for an endpoint in the Henry SDK TypeScript API. You can use the schema returned by this tool to invoke an endpoint with the `invoke_api_endpoint` tool.',
86
- inputSchema: zodToInputSchema(getEndpointSchema),
87
- },
88
- handler: async (client: HenrySDK, args: Record<string, unknown> | undefined) => {
89
- if (!args) {
90
- throw new Error('No endpoint provided');
91
- }
92
- const endpointName = getEndpointSchema.parse(args).endpoint;
93
-
94
- const endpoint = endpoints.find((e) => e.tool.name === endpointName);
95
- if (!endpoint) {
96
- throw new Error(`Endpoint ${endpointName} not found`);
97
- }
98
- return asTextContentResult(endpoint.tool);
99
- },
100
- };
101
-
102
- const invokeEndpointSchema = z.object({
103
- endpoint_name: z.string().describe('The name of the endpoint to invoke.'),
104
- args: z
105
- .record(z.string(), z.any())
106
- .describe(
107
- 'The arguments to pass to the endpoint. This must match the schema returned by the `get_api_endpoint_schema` tool.',
108
- ),
109
- });
110
-
111
- const invokeEndpointTool = {
112
- metadata: {
113
- resource: 'dynamic_tools',
114
- operation: 'write' as const,
115
- tags: [],
116
- },
117
- tool: {
118
- name: 'invoke_api_endpoint',
119
- description:
120
- 'Invoke an endpoint in the Henry SDK TypeScript API. Note: use the `list_api_endpoints` tool to get the list of endpoints and `get_api_endpoint_schema` tool to get the schema for an endpoint.',
121
- inputSchema: zodToInputSchema(invokeEndpointSchema),
122
- },
123
- handler: async (client: HenrySDK, args: Record<string, unknown> | undefined): Promise<ToolCallResult> => {
124
- if (!args) {
125
- throw new Error('No endpoint provided');
126
- }
127
- const { success, data, error } = invokeEndpointSchema.safeParse(args);
128
- if (!success) {
129
- throw new Error(`Invalid arguments for endpoint. ${error?.format()}`);
130
- }
131
- const { endpoint_name, args: endpointArgs } = data;
132
-
133
- const endpoint = endpoints.find((e) => e.tool.name === endpoint_name);
134
- if (!endpoint) {
135
- throw new Error(
136
- `Endpoint ${endpoint_name} not found. Use the \`list_api_endpoints\` tool to get the list of available endpoints.`,
137
- );
138
- }
139
-
140
- try {
141
- // Try to validate the arguments for a better error message
142
- const cabidela = new Cabidela(endpoint.tool.inputSchema, { fullErrors: true });
143
- cabidela.validate(endpointArgs);
144
- } catch (error) {
145
- throw new Error(`Invalid arguments for endpoint ${endpoint_name}:\n${error}`);
146
- }
147
-
148
- return await endpoint.handler(client, endpointArgs);
149
- },
150
- };
151
-
152
- return [getEndpointTool, listEndpointsTool, invokeEndpointTool];
153
- }
package/src/filtering.ts DELETED
@@ -1,18 +0,0 @@
1
- // @ts-nocheck
2
- import initJq from 'jq-web';
3
-
4
- export async function maybeFilter(jqFilter: unknown | undefined, response: any): Promise<any> {
5
- if (jqFilter && typeof jqFilter === 'string') {
6
- return await jq(response, jqFilter);
7
- } else {
8
- return response;
9
- }
10
- }
11
-
12
- async function jq(json: any, jqFilter: string) {
13
- return (await initJq).json(json, jqFilter);
14
- }
15
-
16
- export function isJqError(error: any): error is Error {
17
- return error instanceof Error && 'stderr' in error;
18
- }
@@ -1,60 +0,0 @@
1
- // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- import { isJqError, maybeFilter } from '@henrylabs/mcp/filtering';
4
- import { Metadata, asErrorResult, asTextContentResult } from '@henrylabs/mcp/tools/types';
5
-
6
- import { Tool } from '@modelcontextprotocol/sdk/types.js';
7
- import HenrySDK from '@henrylabs/sdk';
8
-
9
- export const metadata: Metadata = {
10
- resource: 'cart',
11
- operation: 'write',
12
- tags: [],
13
- httpMethod: 'post',
14
- httpPath: '/cart/checkout',
15
- operationId: 'createHostedCheckoutPage',
16
- };
17
-
18
- export const tool: Tool = {
19
- name: 'create_cart_checkout',
20
- description:
21
- "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGenerates a fully-hosted checkout URL for the user's cart. This is the SIMPLEST checkout method.\n\nThe hosted page handles:\n- Order review\n- Shipping address collection\n- Payment information (via Stripe)\n- Order confirmation\n- All UI and validation\n\nReturns: checkout_url (direct link for user to complete purchase)\n\nParameters:\n- auth: true (default) - requires user authentication, false for guest checkout\n\nUse this when:\n- You want a quick, complete checkout solution\n- Don't need custom checkout UI\n- Want Stripe to handle payment collection\n\nFor custom checkout UI, use the headless flow instead:\ncreate_checkout_session → collect_payment_details → confirm_checkout_session\n\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/cart_create_checkout_response',\n $defs: {\n cart_create_checkout_response: {\n type: 'object',\n properties: {\n message: {\n type: 'string'\n },\n status: {\n type: 'string'\n },\n success: {\n type: 'boolean'\n },\n data: {\n type: 'object',\n properties: {\n checkout_url: {\n type: 'string'\n }\n },\n required: [ 'checkout_url'\n ]\n }\n },\n required: [ 'message',\n 'status',\n 'success'\n ]\n }\n }\n}\n```",
22
- inputSchema: {
23
- type: 'object',
24
- properties: {
25
- 'x-user-id': {
26
- type: 'string',
27
- },
28
- auth: {
29
- type: 'boolean',
30
- description: 'Whether authentication is required for checkout (default: true)',
31
- },
32
- region: {
33
- type: 'string',
34
- description: 'ISO 3166-1 alpha-2 country code (2-character lowercase string)',
35
- },
36
- jq_filter: {
37
- type: 'string',
38
- title: 'jq Filter',
39
- description:
40
- 'A jq filter to apply to the response to include certain fields. Consult the output schema in the tool description to see the fields that are available.\n\nFor example: to include only the `name` field in every object of a results array, you can provide ".results[].name".\n\nFor more information, see the [jq documentation](https://jqlang.org/manual/).',
41
- },
42
- },
43
- required: ['x-user-id'],
44
- },
45
- annotations: {},
46
- };
47
-
48
- export const handler = async (client: HenrySDK, args: Record<string, unknown> | undefined) => {
49
- const { jq_filter, ...body } = args as any;
50
- try {
51
- return asTextContentResult(await maybeFilter(jq_filter, await client.cart.createCheckout(body)));
52
- } catch (error) {
53
- if (error instanceof HenrySDK.APIError || isJqError(error)) {
54
- return asErrorResult(error.message);
55
- }
56
- throw error;
57
- }
58
- };
59
-
60
- export default { metadata, tool, handler };
@@ -1,100 +0,0 @@
1
- // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- import { isJqError, maybeFilter } from '@henrylabs/mcp/filtering';
4
- import { Metadata, asErrorResult, asTextContentResult } from '@henrylabs/mcp/tools/types';
5
-
6
- import { Tool } from '@modelcontextprotocol/sdk/types.js';
7
- import HenrySDK from '@henrylabs/sdk';
8
-
9
- export const metadata: Metadata = {
10
- resource: 'cart.items',
11
- operation: 'write',
12
- tags: [],
13
- httpMethod: 'post',
14
- httpPath: '/cart/items',
15
- operationId: 'addCartItems',
16
- };
17
-
18
- export const tool: Tool = {
19
- name: 'add_cart_items',
20
- description:
21
- "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nAdd products to cart or update quantities if already in cart.\n\nRequired fields per product:\n- name: Product name (from retrieve_product_details)\n- price: Price as string, e.g. \"29.99\" (from stores[0].price)\n- productLink: Store URL (from stores[0].link - MUST call retrieve_product_details first)\n- quantity: Number of items\n\nOptional but IMPORTANT:\n- metadata: Object containing variant selections (size, color, etc.)\n Example: {\"size\": \"Large\", \"color\": \"Blue\"}\n- productImageLink: Thumbnail URL (from thumbnails[0])\n- affiliateProductLink: Use instead of productLink for affiliate tracking\n- productId: Include for easier tracking\n\nVARIANT HANDLING:\nIf retrieve_product_details shows variants array, you MUST:\n1. Show variants to user: \"Available sizes: S, M, L, XL\"\n2. Get user's selection\n3. Include in metadata: {\"size\": \"L\"}\n\nOptional: Set checkVariantAvailability: true to verify variants exist at stores\n\nReturns:\n- added_products: New items in cart\n- updated_products: Items with quantity increases\n- cart_summary: total_items and total_unique_products\n- variant_checks: Availability verification results (if requested)\n\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/item_add_response',\n $defs: {\n item_add_response: {\n type: 'object',\n properties: {\n message: {\n type: 'string'\n },\n status: {\n type: 'string'\n },\n success: {\n type: 'boolean'\n },\n data: {\n type: 'object',\n properties: {\n added_products: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: {\n type: 'string'\n },\n price: {\n type: 'string'\n },\n productId: {\n type: 'string'\n },\n quantity: {\n type: 'number'\n }\n },\n required: [ 'name',\n 'price',\n 'productId',\n 'quantity'\n ]\n }\n },\n cart_summary: {\n type: 'object',\n properties: {\n total_items: {\n type: 'number'\n },\n total_unique_products: {\n type: 'number'\n }\n },\n required: [ 'total_items',\n 'total_unique_products'\n ]\n },\n updated_products: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n addedQuantity: {\n type: 'number'\n },\n name: {\n type: 'string'\n },\n previousQuantity: {\n type: 'number'\n },\n price: {\n type: 'string'\n },\n productId: {\n type: 'string'\n },\n quantity: {\n type: 'number'\n }\n },\n required: [ 'addedQuantity',\n 'name',\n 'previousQuantity',\n 'price',\n 'productId',\n 'quantity'\n ]\n }\n },\n variant_checks: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n productId: {\n type: 'string'\n },\n status: {\n type: 'string'\n },\n variantCheckRequestId: {\n type: 'string'\n }\n },\n required: [ 'productId',\n 'status',\n 'variantCheckRequestId'\n ]\n }\n }\n },\n required: [ 'added_products',\n 'cart_summary',\n 'updated_products'\n ]\n }\n },\n required: [ 'message',\n 'status',\n 'success'\n ]\n }\n }\n}\n```",
22
- inputSchema: {
23
- type: 'object',
24
- properties: {
25
- productsDetails: {
26
- type: 'array',
27
- items: {
28
- type: 'object',
29
- properties: {
30
- name: {
31
- type: 'string',
32
- description: 'Product name',
33
- },
34
- price: {
35
- type: 'string',
36
- description: 'Product price',
37
- },
38
- productLink: {
39
- type: 'string',
40
- description: 'Product link',
41
- },
42
- quantity: {
43
- type: 'number',
44
- description: 'Quantity',
45
- },
46
- affiliateProductLink: {
47
- type: 'string',
48
- description:
49
- 'Affiliate product link (if provided, will be used instead of productLink for order fulfillment)',
50
- },
51
- metadata: {
52
- type: 'object',
53
- description: 'Product metadata',
54
- additionalProperties: true,
55
- },
56
- productId: {
57
- type: 'string',
58
- description: 'Product Id',
59
- },
60
- productImageLink: {
61
- type: 'string',
62
- description: 'Product image link (thumbnail)',
63
- },
64
- },
65
- required: ['name', 'price', 'productLink', 'quantity'],
66
- },
67
- },
68
- 'x-user-id': {
69
- type: 'string',
70
- },
71
- checkVariantAvailability: {
72
- type: 'boolean',
73
- description:
74
- 'Whether to check variant availability after adding to cart. If true, variant check requests will be created for products with metadata and requestIds returned.',
75
- },
76
- jq_filter: {
77
- type: 'string',
78
- title: 'jq Filter',
79
- description:
80
- 'A jq filter to apply to the response to include certain fields. Consult the output schema in the tool description to see the fields that are available.\n\nFor example: to include only the `name` field in every object of a results array, you can provide ".results[].name".\n\nFor more information, see the [jq documentation](https://jqlang.org/manual/).',
81
- },
82
- },
83
- required: ['productsDetails', 'x-user-id'],
84
- },
85
- annotations: {},
86
- };
87
-
88
- export const handler = async (client: HenrySDK, args: Record<string, unknown> | undefined) => {
89
- const { jq_filter, ...body } = args as any;
90
- try {
91
- return asTextContentResult(await maybeFilter(jq_filter, await client.cart.items.add(body)));
92
- } catch (error) {
93
- if (error instanceof HenrySDK.APIError || isJqError(error)) {
94
- return asErrorResult(error.message);
95
- }
96
- throw error;
97
- }
98
- };
99
-
100
- export default { metadata, tool, handler };
@@ -1,54 +0,0 @@
1
- // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- import { isJqError, maybeFilter } from '@henrylabs/mcp/filtering';
4
- import { Metadata, asErrorResult, asTextContentResult } from '@henrylabs/mcp/tools/types';
5
-
6
- import { Tool } from '@modelcontextprotocol/sdk/types.js';
7
- import HenrySDK from '@henrylabs/sdk';
8
-
9
- export const metadata: Metadata = {
10
- resource: 'cart.items',
11
- operation: 'write',
12
- tags: [],
13
- httpMethod: 'delete',
14
- httpPath: '/cart/items',
15
- operationId: 'deleteAllCartItems',
16
- };
17
-
18
- export const tool: Tool = {
19
- name: 'clear_cart_items',
20
- description:
21
- "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRemove ALL products from the cart. Cannot be undone.\n\nUse when:\n- User wants to start over\n- Clearing abandoned cart\n- After successful order completion\n\nReturns success confirmation message.\n\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/item_clear_response',\n $defs: {\n item_clear_response: {\n type: 'object',\n properties: {\n message: {\n type: 'string'\n },\n status: {\n type: 'string'\n },\n success: {\n type: 'boolean'\n }\n },\n required: [ 'message',\n 'status',\n 'success'\n ]\n }\n }\n}\n```",
22
- inputSchema: {
23
- type: 'object',
24
- properties: {
25
- 'x-user-id': {
26
- type: 'string',
27
- },
28
- jq_filter: {
29
- type: 'string',
30
- title: 'jq Filter',
31
- description:
32
- 'A jq filter to apply to the response to include certain fields. Consult the output schema in the tool description to see the fields that are available.\n\nFor example: to include only the `name` field in every object of a results array, you can provide ".results[].name".\n\nFor more information, see the [jq documentation](https://jqlang.org/manual/).',
33
- },
34
- },
35
- required: ['x-user-id'],
36
- },
37
- annotations: {
38
- idempotentHint: true,
39
- },
40
- };
41
-
42
- export const handler = async (client: HenrySDK, args: Record<string, unknown> | undefined) => {
43
- const { jq_filter, ...body } = args as any;
44
- try {
45
- return asTextContentResult(await maybeFilter(jq_filter, await client.cart.items.clear(body)));
46
- } catch (error) {
47
- if (error instanceof HenrySDK.APIError || isJqError(error)) {
48
- return asErrorResult(error.message);
49
- }
50
- throw error;
51
- }
52
- };
53
-
54
- export default { metadata, tool, handler };
@@ -1,54 +0,0 @@
1
- // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- import { isJqError, maybeFilter } from '@henrylabs/mcp/filtering';
4
- import { Metadata, asErrorResult, asTextContentResult } from '@henrylabs/mcp/tools/types';
5
-
6
- import { Tool } from '@modelcontextprotocol/sdk/types.js';
7
- import HenrySDK from '@henrylabs/sdk';
8
-
9
- export const metadata: Metadata = {
10
- resource: 'cart.items',
11
- operation: 'read',
12
- tags: [],
13
- httpMethod: 'get',
14
- httpPath: '/cart/items',
15
- operationId: 'getCartItems',
16
- };
17
-
18
- export const tool: Tool = {
19
- name: 'list_cart_items',
20
- description:
21
- "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetrieve all products currently in the user's cart.\n\nReturns products array with:\n- name, price, productLink, quantity\n- productId (if provided when added)\n- metadata (variant selections)\n- productImageLink (thumbnail)\n- affiliateProductLink (if used)\n\nUse this to:\n- Show cart contents before checkout\n- Calculate totals\n- Verify items before creating checkout\n\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/item_list_response',\n $defs: {\n item_list_response: {\n type: 'object',\n properties: {\n message: {\n type: 'string'\n },\n status: {\n type: 'string'\n },\n success: {\n type: 'boolean'\n },\n data: {\n type: 'object',\n properties: {\n products: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Product name'\n },\n price: {\n type: 'string',\n description: 'Product price'\n },\n productLink: {\n type: 'string',\n description: 'Product link'\n },\n quantity: {\n type: 'number',\n description: 'Quantity'\n },\n affiliateProductLink: {\n type: 'string',\n description: 'Affiliate product link (if provided, will be used instead of productLink for order fulfillment)'\n },\n metadata: {\n type: 'object',\n description: 'Product metadata',\n additionalProperties: true\n },\n productId: {\n type: 'string',\n description: 'Product Id'\n },\n productImageLink: {\n type: 'string',\n description: 'Product image link (thumbnail)'\n }\n },\n required: [ 'name',\n 'price',\n 'productLink',\n 'quantity'\n ]\n }\n }\n },\n required: [ 'products'\n ]\n }\n },\n required: [ 'message',\n 'status',\n 'success'\n ]\n }\n }\n}\n```",
22
- inputSchema: {
23
- type: 'object',
24
- properties: {
25
- 'x-user-id': {
26
- type: 'string',
27
- },
28
- jq_filter: {
29
- type: 'string',
30
- title: 'jq Filter',
31
- description:
32
- 'A jq filter to apply to the response to include certain fields. Consult the output schema in the tool description to see the fields that are available.\n\nFor example: to include only the `name` field in every object of a results array, you can provide ".results[].name".\n\nFor more information, see the [jq documentation](https://jqlang.org/manual/).',
33
- },
34
- },
35
- required: ['x-user-id'],
36
- },
37
- annotations: {
38
- readOnlyHint: true,
39
- },
40
- };
41
-
42
- export const handler = async (client: HenrySDK, args: Record<string, unknown> | undefined) => {
43
- const { jq_filter, ...body } = args as any;
44
- try {
45
- return asTextContentResult(await maybeFilter(jq_filter, await client.cart.items.list(body)));
46
- } catch (error) {
47
- if (error instanceof HenrySDK.APIError || isJqError(error)) {
48
- return asErrorResult(error.message);
49
- }
50
- throw error;
51
- }
52
- };
53
-
54
- export default { metadata, tool, handler };
@@ -1,57 +0,0 @@
1
- // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- import { isJqError, maybeFilter } from '@henrylabs/mcp/filtering';
4
- import { Metadata, asErrorResult, asTextContentResult } from '@henrylabs/mcp/tools/types';
5
-
6
- import { Tool } from '@modelcontextprotocol/sdk/types.js';
7
- import HenrySDK from '@henrylabs/sdk';
8
-
9
- export const metadata: Metadata = {
10
- resource: 'cart.items',
11
- operation: 'write',
12
- tags: [],
13
- httpMethod: 'delete',
14
- httpPath: '/cart/items/{productId}',
15
- operationId: 'deleteCartItem',
16
- };
17
-
18
- export const tool: Tool = {
19
- name: 'remove_cart_items',
20
- description:
21
- "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRemove a specific product from the cart by its productId.\n\nRequired: productId (must match the ID used when adding item)\n\nReturns success confirmation message.\n\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/item_remove_response',\n $defs: {\n item_remove_response: {\n type: 'object',\n properties: {\n message: {\n type: 'string'\n },\n status: {\n type: 'string'\n },\n success: {\n type: 'boolean'\n }\n },\n required: [ 'message',\n 'status',\n 'success'\n ]\n }\n }\n}\n```",
22
- inputSchema: {
23
- type: 'object',
24
- properties: {
25
- productId: {
26
- type: 'string',
27
- },
28
- 'x-user-id': {
29
- type: 'string',
30
- },
31
- jq_filter: {
32
- type: 'string',
33
- title: 'jq Filter',
34
- description:
35
- 'A jq filter to apply to the response to include certain fields. Consult the output schema in the tool description to see the fields that are available.\n\nFor example: to include only the `name` field in every object of a results array, you can provide ".results[].name".\n\nFor more information, see the [jq documentation](https://jqlang.org/manual/).',
36
- },
37
- },
38
- required: ['productId', 'x-user-id'],
39
- },
40
- annotations: {
41
- idempotentHint: true,
42
- },
43
- };
44
-
45
- export const handler = async (client: HenrySDK, args: Record<string, unknown> | undefined) => {
46
- const { productId, jq_filter, ...body } = args as any;
47
- try {
48
- return asTextContentResult(await maybeFilter(jq_filter, await client.cart.items.remove(productId, body)));
49
- } catch (error) {
50
- if (error instanceof HenrySDK.APIError || isJqError(error)) {
51
- return asErrorResult(error.message);
52
- }
53
- throw error;
54
- }
55
- };
56
-
57
- export default { metadata, tool, handler };
@@ -1,87 +0,0 @@
1
- // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- import { Metadata, Endpoint, HandlerFunction } from './types';
4
-
5
- export { Metadata, Endpoint, HandlerFunction };
6
-
7
- import retrieve_product_details from './products/retrieve-product-details';
8
- import search_products from './products/search-products';
9
- import create_cart_checkout from './cart/create-cart-checkout';
10
- import list_cart_items from './cart/items/list-cart-items';
11
- import add_cart_items from './cart/items/add-cart-items';
12
- import clear_cart_items from './cart/items/clear-cart-items';
13
- import remove_cart_items from './cart/items/remove-cart-items';
14
- import retrieve_status_orders from './orders/retrieve-status-orders';
15
- import collect_payment_details from './wallet/collect-payment-details';
16
-
17
- export const endpoints: Endpoint[] = [];
18
-
19
- function addEndpoint(endpoint: Endpoint) {
20
- endpoints.push(endpoint);
21
- }
22
-
23
- addEndpoint(retrieve_product_details);
24
- addEndpoint(search_products);
25
- addEndpoint(create_cart_checkout);
26
- addEndpoint(list_cart_items);
27
- addEndpoint(add_cart_items);
28
- addEndpoint(clear_cart_items);
29
- addEndpoint(remove_cart_items);
30
- addEndpoint(retrieve_status_orders);
31
- addEndpoint(collect_payment_details);
32
-
33
- export type Filter = {
34
- type: 'resource' | 'operation' | 'tag' | 'tool';
35
- op: 'include' | 'exclude';
36
- value: string;
37
- };
38
-
39
- export function query(filters: Filter[], endpoints: Endpoint[]): Endpoint[] {
40
- const allExcludes = filters.length > 0 && filters.every((filter) => filter.op === 'exclude');
41
- const unmatchedFilters = new Set(filters);
42
-
43
- const filtered = endpoints.filter((endpoint: Endpoint) => {
44
- let included = false || allExcludes;
45
-
46
- for (const filter of filters) {
47
- if (match(filter, endpoint)) {
48
- unmatchedFilters.delete(filter);
49
- included = filter.op === 'include';
50
- }
51
- }
52
-
53
- return included;
54
- });
55
-
56
- // Check if any filters didn't match
57
- const unmatched = Array.from(unmatchedFilters).filter((f) => f.type === 'tool' || f.type === 'resource');
58
- if (unmatched.length > 0) {
59
- throw new Error(
60
- `The following filters did not match any endpoints: ${unmatched
61
- .map((f) => `${f.type}=${f.value}`)
62
- .join(', ')}`,
63
- );
64
- }
65
-
66
- return filtered;
67
- }
68
-
69
- function match({ type, value }: Filter, endpoint: Endpoint): boolean {
70
- switch (type) {
71
- case 'resource': {
72
- const regexStr = '^' + normalizeResource(value).replace(/\*/g, '.*') + '$';
73
- const regex = new RegExp(regexStr);
74
- return regex.test(normalizeResource(endpoint.metadata.resource));
75
- }
76
- case 'operation':
77
- return endpoint.metadata.operation === value;
78
- case 'tag':
79
- return endpoint.metadata.tags.includes(value);
80
- case 'tool':
81
- return endpoint.tool.name === value;
82
- }
83
- }
84
-
85
- function normalizeResource(resource: string): string {
86
- return resource.toLowerCase().replace(/[^a-z.*\-_]*/g, '');
87
- }
@@ -1,54 +0,0 @@
1
- // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
-
3
- import { isJqError, maybeFilter } from '@henrylabs/mcp/filtering';
4
- import { Metadata, asErrorResult, asTextContentResult } from '@henrylabs/mcp/tools/types';
5
-
6
- import { Tool } from '@modelcontextprotocol/sdk/types.js';
7
- import HenrySDK from '@henrylabs/sdk';
8
-
9
- export const metadata: Metadata = {
10
- resource: 'orders',
11
- operation: 'read',
12
- tags: [],
13
- httpMethod: 'get',
14
- httpPath: '/orders/{orderId}',
15
- operationId: 'getOrderStatus',
16
- };
17
-
18
- export const tool: Tool = {
19
- name: 'retrieve_status_orders',
20
- description:
21
- "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nCheck the status and details of an order using its order ID.\n\nReturns:\n- id: Order ID\n- status: Current order status (e.g., \"processing\", \"shipped\", \"delivered\")\n- statusMessage: Detailed status description\n- products: Array with productName, quantity, productMetadata (variants)\n- currency, subtotal, shipping, tax, grandTotal\n- shippingDetails: Full delivery address\n- userId: User who placed order\n- cardLast4: Payment card used (last 4 digits)\n\nUse for:\n- Order tracking\n- Status updates\n- Order history\n- Customer support\n\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/order_retrieve_status_response',\n $defs: {\n order_retrieve_status_response: {\n type: 'object',\n properties: {\n message: {\n type: 'string'\n },\n status: {\n type: 'string'\n },\n success: {\n type: 'boolean'\n },\n data: {\n type: 'object',\n properties: {\n id: {\n type: 'string'\n },\n currency: {\n type: 'string'\n },\n grandTotal: {\n type: 'string'\n },\n products: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n productName: {\n type: 'string'\n },\n quantity: {\n type: 'number'\n },\n productMetadata: {\n type: 'object',\n additionalProperties: true\n }\n },\n required: [ 'productName',\n 'quantity'\n ]\n }\n },\n shipping: {\n type: 'string'\n },\n status: {\n type: 'string'\n },\n statusMessage: {\n type: 'string'\n },\n subtotal: {\n type: 'string'\n },\n tax: {\n type: 'string'\n },\n userId: {\n type: 'string'\n },\n shippingDetails: {\n type: 'object',\n properties: {\n addressLine1: {\n type: 'string'\n },\n city: {\n type: 'string'\n },\n countryCode: {\n type: 'string'\n },\n email: {\n type: 'string'\n },\n fullName: {\n type: 'string'\n },\n phoneNumber: {\n type: 'string'\n },\n postalCode: {\n type: 'string'\n },\n stateOrProvince: {\n type: 'string'\n },\n addressLine2: {\n type: 'string'\n }\n },\n required: [ 'addressLine1',\n 'city',\n 'countryCode',\n 'email',\n 'fullName',\n 'phoneNumber',\n 'postalCode',\n 'stateOrProvince'\n ]\n }\n },\n required: [ 'id',\n 'currency',\n 'grandTotal',\n 'products',\n 'shipping',\n 'status',\n 'statusMessage',\n 'subtotal',\n 'tax',\n 'userId'\n ]\n }\n },\n required: [ 'message',\n 'status',\n 'success'\n ]\n }\n }\n}\n```",
22
- inputSchema: {
23
- type: 'object',
24
- properties: {
25
- orderId: {
26
- type: 'string',
27
- },
28
- jq_filter: {
29
- type: 'string',
30
- title: 'jq Filter',
31
- description:
32
- 'A jq filter to apply to the response to include certain fields. Consult the output schema in the tool description to see the fields that are available.\n\nFor example: to include only the `name` field in every object of a results array, you can provide ".results[].name".\n\nFor more information, see the [jq documentation](https://jqlang.org/manual/).',
33
- },
34
- },
35
- required: ['orderId'],
36
- },
37
- annotations: {
38
- readOnlyHint: true,
39
- },
40
- };
41
-
42
- export const handler = async (client: HenrySDK, args: Record<string, unknown> | undefined) => {
43
- const { orderId, jq_filter, ...body } = args as any;
44
- try {
45
- return asTextContentResult(await maybeFilter(jq_filter, await client.orders.retrieveStatus(orderId)));
46
- } catch (error) {
47
- if (error instanceof HenrySDK.APIError || isJqError(error)) {
48
- return asErrorResult(error.message);
49
- }
50
- throw error;
51
- }
52
- };
53
-
54
- export default { metadata, tool, handler };