@solidcommerce/mcp-server 2.0.0-alpha.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 (268) hide show
  1. package/README.md +74 -0
  2. package/bin/solidcommerce-mcp.js +8 -0
  3. package/dist/audit/auditClient.d.ts +51 -0
  4. package/dist/audit/auditClient.d.ts.map +1 -0
  5. package/dist/audit/auditClient.js +93 -0
  6. package/dist/audit/auditClient.js.map +1 -0
  7. package/dist/auth/apiKey.d.ts +44 -0
  8. package/dist/auth/apiKey.d.ts.map +1 -0
  9. package/dist/auth/apiKey.js +80 -0
  10. package/dist/auth/apiKey.js.map +1 -0
  11. package/dist/auth/oauth.d.ts +108 -0
  12. package/dist/auth/oauth.d.ts.map +1 -0
  13. package/dist/auth/oauth.js +300 -0
  14. package/dist/auth/oauth.js.map +1 -0
  15. package/dist/generator/fromOpenApi.d.ts +54 -0
  16. package/dist/generator/fromOpenApi.d.ts.map +1 -0
  17. package/dist/generator/fromOpenApi.js +411 -0
  18. package/dist/generator/fromOpenApi.js.map +1 -0
  19. package/dist/generator/schemaToZod.d.ts +81 -0
  20. package/dist/generator/schemaToZod.d.ts.map +1 -0
  21. package/dist/generator/schemaToZod.js +277 -0
  22. package/dist/generator/schemaToZod.js.map +1 -0
  23. package/dist/generator/scopeInference.d.ts +26 -0
  24. package/dist/generator/scopeInference.d.ts.map +1 -0
  25. package/dist/generator/scopeInference.js +91 -0
  26. package/dist/generator/scopeInference.js.map +1 -0
  27. package/dist/index.d.ts +2 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +106 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/server/buildServer.d.ts +35 -0
  32. package/dist/server/buildServer.d.ts.map +1 -0
  33. package/dist/server/buildServer.js +104 -0
  34. package/dist/server/buildServer.js.map +1 -0
  35. package/dist/server/dispatcher.d.ts +14 -0
  36. package/dist/server/dispatcher.d.ts.map +1 -0
  37. package/dist/server/dispatcher.js +190 -0
  38. package/dist/server/dispatcher.js.map +1 -0
  39. package/dist/session.d.ts +9 -0
  40. package/dist/session.d.ts.map +1 -0
  41. package/dist/session.js +11 -0
  42. package/dist/session.js.map +1 -0
  43. package/dist/telemetry/hostName.d.ts +26 -0
  44. package/dist/telemetry/hostName.d.ts.map +1 -0
  45. package/dist/telemetry/hostName.js +80 -0
  46. package/dist/telemetry/hostName.js.map +1 -0
  47. package/dist/tools/contract.d.ts +125 -0
  48. package/dist/tools/contract.d.ts.map +1 -0
  49. package/dist/tools/contract.js +101 -0
  50. package/dist/tools/contract.js.map +1 -0
  51. package/dist/tools/foundation/catalog_amazon_items_list.d.ts +4 -0
  52. package/dist/tools/foundation/catalog_amazon_items_list.d.ts.map +1 -0
  53. package/dist/tools/foundation/catalog_amazon_items_list.js +47 -0
  54. package/dist/tools/foundation/catalog_amazon_items_list.js.map +1 -0
  55. package/dist/tools/foundation/catalog_attribute_filters_list.d.ts +4 -0
  56. package/dist/tools/foundation/catalog_attribute_filters_list.d.ts.map +1 -0
  57. package/dist/tools/foundation/catalog_attribute_filters_list.js +47 -0
  58. package/dist/tools/foundation/catalog_attribute_filters_list.js.map +1 -0
  59. package/dist/tools/foundation/catalog_attribute_tags_list.d.ts +4 -0
  60. package/dist/tools/foundation/catalog_attribute_tags_list.d.ts.map +1 -0
  61. package/dist/tools/foundation/catalog_attribute_tags_list.js +47 -0
  62. package/dist/tools/foundation/catalog_attribute_tags_list.js.map +1 -0
  63. package/dist/tools/foundation/catalog_attributes_list.d.ts +4 -0
  64. package/dist/tools/foundation/catalog_attributes_list.d.ts.map +1 -0
  65. package/dist/tools/foundation/catalog_attributes_list.js +57 -0
  66. package/dist/tools/foundation/catalog_attributes_list.js.map +1 -0
  67. package/dist/tools/foundation/catalog_column_views_default_list.d.ts +4 -0
  68. package/dist/tools/foundation/catalog_column_views_default_list.d.ts.map +1 -0
  69. package/dist/tools/foundation/catalog_column_views_default_list.js +47 -0
  70. package/dist/tools/foundation/catalog_column_views_default_list.js.map +1 -0
  71. package/dist/tools/foundation/catalog_column_views_list.d.ts +4 -0
  72. package/dist/tools/foundation/catalog_column_views_list.d.ts.map +1 -0
  73. package/dist/tools/foundation/catalog_column_views_list.js +47 -0
  74. package/dist/tools/foundation/catalog_column_views_list.js.map +1 -0
  75. package/dist/tools/foundation/catalog_ebay_categories_list.d.ts +4 -0
  76. package/dist/tools/foundation/catalog_ebay_categories_list.d.ts.map +1 -0
  77. package/dist/tools/foundation/catalog_ebay_categories_list.js +56 -0
  78. package/dist/tools/foundation/catalog_ebay_categories_list.js.map +1 -0
  79. package/dist/tools/foundation/catalog_ebay_category_specifics_list.d.ts +4 -0
  80. package/dist/tools/foundation/catalog_ebay_category_specifics_list.d.ts.map +1 -0
  81. package/dist/tools/foundation/catalog_ebay_category_specifics_list.js +56 -0
  82. package/dist/tools/foundation/catalog_ebay_category_specifics_list.js.map +1 -0
  83. package/dist/tools/foundation/catalog_ebay_listing_templates_list.d.ts +4 -0
  84. package/dist/tools/foundation/catalog_ebay_listing_templates_list.d.ts.map +1 -0
  85. package/dist/tools/foundation/catalog_ebay_listing_templates_list.js +47 -0
  86. package/dist/tools/foundation/catalog_ebay_listing_templates_list.js.map +1 -0
  87. package/dist/tools/foundation/catalog_ebay_product_search_list.d.ts +4 -0
  88. package/dist/tools/foundation/catalog_ebay_product_search_list.d.ts.map +1 -0
  89. package/dist/tools/foundation/catalog_ebay_product_search_list.js +56 -0
  90. package/dist/tools/foundation/catalog_ebay_product_search_list.js.map +1 -0
  91. package/dist/tools/foundation/catalog_ebay_template_fields_list.d.ts +4 -0
  92. package/dist/tools/foundation/catalog_ebay_template_fields_list.d.ts.map +1 -0
  93. package/dist/tools/foundation/catalog_ebay_template_fields_list.js +47 -0
  94. package/dist/tools/foundation/catalog_ebay_template_fields_list.js.map +1 -0
  95. package/dist/tools/foundation/catalog_ebay_variation_groups_list.d.ts +4 -0
  96. package/dist/tools/foundation/catalog_ebay_variation_groups_list.d.ts.map +1 -0
  97. package/dist/tools/foundation/catalog_ebay_variation_groups_list.js +56 -0
  98. package/dist/tools/foundation/catalog_ebay_variation_groups_list.js.map +1 -0
  99. package/dist/tools/foundation/catalog_inventory_sources_list.d.ts +4 -0
  100. package/dist/tools/foundation/catalog_inventory_sources_list.d.ts.map +1 -0
  101. package/dist/tools/foundation/catalog_inventory_sources_list.js +47 -0
  102. package/dist/tools/foundation/catalog_inventory_sources_list.js.map +1 -0
  103. package/dist/tools/foundation/catalog_listing_rules_list.d.ts +4 -0
  104. package/dist/tools/foundation/catalog_listing_rules_list.d.ts.map +1 -0
  105. package/dist/tools/foundation/catalog_listing_rules_list.js +47 -0
  106. package/dist/tools/foundation/catalog_listing_rules_list.js.map +1 -0
  107. package/dist/tools/foundation/catalog_listing_templates_list.d.ts +4 -0
  108. package/dist/tools/foundation/catalog_listing_templates_list.d.ts.map +1 -0
  109. package/dist/tools/foundation/catalog_listing_templates_list.js +47 -0
  110. package/dist/tools/foundation/catalog_listing_templates_list.js.map +1 -0
  111. package/dist/tools/foundation/catalog_manufacturers_all_list.d.ts +4 -0
  112. package/dist/tools/foundation/catalog_manufacturers_all_list.d.ts.map +1 -0
  113. package/dist/tools/foundation/catalog_manufacturers_all_list.js +47 -0
  114. package/dist/tools/foundation/catalog_manufacturers_all_list.js.map +1 -0
  115. package/dist/tools/foundation/catalog_manufacturers_list.d.ts +4 -0
  116. package/dist/tools/foundation/catalog_manufacturers_list.d.ts.map +1 -0
  117. package/dist/tools/foundation/catalog_manufacturers_list.js +47 -0
  118. package/dist/tools/foundation/catalog_manufacturers_list.js.map +1 -0
  119. package/dist/tools/foundation/catalog_market_lists_list.d.ts +4 -0
  120. package/dist/tools/foundation/catalog_market_lists_list.d.ts.map +1 -0
  121. package/dist/tools/foundation/catalog_market_lists_list.js +47 -0
  122. package/dist/tools/foundation/catalog_market_lists_list.js.map +1 -0
  123. package/dist/tools/foundation/catalog_product_usage_filters_list.d.ts +4 -0
  124. package/dist/tools/foundation/catalog_product_usage_filters_list.d.ts.map +1 -0
  125. package/dist/tools/foundation/catalog_product_usage_filters_list.js +47 -0
  126. package/dist/tools/foundation/catalog_product_usage_filters_list.js.map +1 -0
  127. package/dist/tools/foundation/catalog_product_usage_list.d.ts +4 -0
  128. package/dist/tools/foundation/catalog_product_usage_list.d.ts.map +1 -0
  129. package/dist/tools/foundation/catalog_product_usage_list.js +61 -0
  130. package/dist/tools/foundation/catalog_product_usage_list.js.map +1 -0
  131. package/dist/tools/foundation/catalog_product_usage_totals_list.d.ts +4 -0
  132. package/dist/tools/foundation/catalog_product_usage_totals_list.d.ts.map +1 -0
  133. package/dist/tools/foundation/catalog_product_usage_totals_list.js +58 -0
  134. package/dist/tools/foundation/catalog_product_usage_totals_list.js.map +1 -0
  135. package/dist/tools/foundation/catalog_products_generate_sku_list.d.ts +4 -0
  136. package/dist/tools/foundation/catalog_products_generate_sku_list.d.ts.map +1 -0
  137. package/dist/tools/foundation/catalog_products_generate_sku_list.js +47 -0
  138. package/dist/tools/foundation/catalog_products_generate_sku_list.js.map +1 -0
  139. package/dist/tools/foundation/catalog_products_list.d.ts +4 -0
  140. package/dist/tools/foundation/catalog_products_list.d.ts.map +1 -0
  141. package/dist/tools/foundation/catalog_products_list.js +60 -0
  142. package/dist/tools/foundation/catalog_products_list.js.map +1 -0
  143. package/dist/tools/foundation/catalog_taxonomy_channels_list.d.ts +4 -0
  144. package/dist/tools/foundation/catalog_taxonomy_channels_list.d.ts.map +1 -0
  145. package/dist/tools/foundation/catalog_taxonomy_channels_list.js +47 -0
  146. package/dist/tools/foundation/catalog_taxonomy_channels_list.js.map +1 -0
  147. package/dist/tools/foundation/catalog_taxonomy_mappings_list.d.ts +4 -0
  148. package/dist/tools/foundation/catalog_taxonomy_mappings_list.d.ts.map +1 -0
  149. package/dist/tools/foundation/catalog_taxonomy_mappings_list.js +56 -0
  150. package/dist/tools/foundation/catalog_taxonomy_mappings_list.js.map +1 -0
  151. package/dist/tools/foundation/catalog_taxonomy_product_values_list.d.ts +4 -0
  152. package/dist/tools/foundation/catalog_taxonomy_product_values_list.d.ts.map +1 -0
  153. package/dist/tools/foundation/catalog_taxonomy_product_values_list.js +57 -0
  154. package/dist/tools/foundation/catalog_taxonomy_product_values_list.js.map +1 -0
  155. package/dist/tools/foundation/catalog_tree_list.d.ts +4 -0
  156. package/dist/tools/foundation/catalog_tree_list.d.ts.map +1 -0
  157. package/dist/tools/foundation/catalog_tree_list.js +47 -0
  158. package/dist/tools/foundation/catalog_tree_list.js.map +1 -0
  159. package/dist/tools/foundation/crm_customers_list.d.ts +4 -0
  160. package/dist/tools/foundation/crm_customers_list.d.ts.map +1 -0
  161. package/dist/tools/foundation/crm_customers_list.js +59 -0
  162. package/dist/tools/foundation/crm_customers_list.js.map +1 -0
  163. package/dist/tools/foundation/fulfillment_manifests_list.d.ts +4 -0
  164. package/dist/tools/foundation/fulfillment_manifests_list.d.ts.map +1 -0
  165. package/dist/tools/foundation/fulfillment_manifests_list.js +47 -0
  166. package/dist/tools/foundation/fulfillment_manifests_list.js.map +1 -0
  167. package/dist/tools/foundation/fulfillment_ship_now_addresses_list.d.ts +4 -0
  168. package/dist/tools/foundation/fulfillment_ship_now_addresses_list.d.ts.map +1 -0
  169. package/dist/tools/foundation/fulfillment_ship_now_addresses_list.js +47 -0
  170. package/dist/tools/foundation/fulfillment_ship_now_addresses_list.js.map +1 -0
  171. package/dist/tools/foundation/fulfillment_ship_now_dictionaries_list.d.ts +4 -0
  172. package/dist/tools/foundation/fulfillment_ship_now_dictionaries_list.d.ts.map +1 -0
  173. package/dist/tools/foundation/fulfillment_ship_now_dictionaries_list.js +56 -0
  174. package/dist/tools/foundation/fulfillment_ship_now_dictionaries_list.js.map +1 -0
  175. package/dist/tools/foundation/index.d.ts +8 -0
  176. package/dist/tools/foundation/index.d.ts.map +1 -0
  177. package/dist/tools/foundation/index.js +93 -0
  178. package/dist/tools/foundation/index.js.map +1 -0
  179. package/dist/tools/foundation/inventory_alert_rules_list.d.ts +4 -0
  180. package/dist/tools/foundation/inventory_alert_rules_list.d.ts.map +1 -0
  181. package/dist/tools/foundation/inventory_alert_rules_list.js +47 -0
  182. package/dist/tools/foundation/inventory_alert_rules_list.js.map +1 -0
  183. package/dist/tools/foundation/inventory_alert_settings_list.d.ts +4 -0
  184. package/dist/tools/foundation/inventory_alert_settings_list.d.ts.map +1 -0
  185. package/dist/tools/foundation/inventory_alert_settings_list.js +47 -0
  186. package/dist/tools/foundation/inventory_alert_settings_list.js.map +1 -0
  187. package/dist/tools/foundation/inventory_analytics_alert_count_list.d.ts +4 -0
  188. package/dist/tools/foundation/inventory_analytics_alert_count_list.d.ts.map +1 -0
  189. package/dist/tools/foundation/inventory_analytics_alert_count_list.js +47 -0
  190. package/dist/tools/foundation/inventory_analytics_alert_count_list.js.map +1 -0
  191. package/dist/tools/foundation/inventory_rules_list.d.ts +4 -0
  192. package/dist/tools/foundation/inventory_rules_list.d.ts.map +1 -0
  193. package/dist/tools/foundation/inventory_rules_list.js +47 -0
  194. package/dist/tools/foundation/inventory_rules_list.js.map +1 -0
  195. package/dist/tools/foundation/inventory_rules_periods_list.d.ts +4 -0
  196. package/dist/tools/foundation/inventory_rules_periods_list.d.ts.map +1 -0
  197. package/dist/tools/foundation/inventory_rules_periods_list.js +47 -0
  198. package/dist/tools/foundation/inventory_rules_periods_list.js.map +1 -0
  199. package/dist/tools/foundation/inventory_seasonal_factors_list.d.ts +4 -0
  200. package/dist/tools/foundation/inventory_seasonal_factors_list.d.ts.map +1 -0
  201. package/dist/tools/foundation/inventory_seasonal_factors_list.js +47 -0
  202. package/dist/tools/foundation/inventory_seasonal_factors_list.js.map +1 -0
  203. package/dist/tools/foundation/inventory_warehouses_list.d.ts +4 -0
  204. package/dist/tools/foundation/inventory_warehouses_list.d.ts.map +1 -0
  205. package/dist/tools/foundation/inventory_warehouses_list.js +47 -0
  206. package/dist/tools/foundation/inventory_warehouses_list.js.map +1 -0
  207. package/dist/tools/foundation/listings_dictionary_marketplace_locales_list.d.ts +4 -0
  208. package/dist/tools/foundation/listings_dictionary_marketplace_locales_list.d.ts.map +1 -0
  209. package/dist/tools/foundation/listings_dictionary_marketplace_locales_list.js +56 -0
  210. package/dist/tools/foundation/listings_dictionary_marketplace_locales_list.js.map +1 -0
  211. package/dist/tools/foundation/listings_dictionary_marketplaces_list.d.ts +4 -0
  212. package/dist/tools/foundation/listings_dictionary_marketplaces_list.d.ts.map +1 -0
  213. package/dist/tools/foundation/listings_dictionary_marketplaces_list.js +47 -0
  214. package/dist/tools/foundation/listings_dictionary_marketplaces_list.js.map +1 -0
  215. package/dist/tools/tasks/bulk_update_prices.d.ts +4 -0
  216. package/dist/tools/tasks/bulk_update_prices.d.ts.map +1 -0
  217. package/dist/tools/tasks/bulk_update_prices.js +96 -0
  218. package/dist/tools/tasks/bulk_update_prices.js.map +1 -0
  219. package/dist/tools/tasks/cancel_order_with_reason.d.ts +4 -0
  220. package/dist/tools/tasks/cancel_order_with_reason.d.ts.map +1 -0
  221. package/dist/tools/tasks/cancel_order_with_reason.js +117 -0
  222. package/dist/tools/tasks/cancel_order_with_reason.js.map +1 -0
  223. package/dist/tools/tasks/check_listing_health.d.ts +4 -0
  224. package/dist/tools/tasks/check_listing_health.d.ts.map +1 -0
  225. package/dist/tools/tasks/check_listing_health.js +123 -0
  226. package/dist/tools/tasks/check_listing_health.js.map +1 -0
  227. package/dist/tools/tasks/create_and_submit_purchase_order.d.ts +4 -0
  228. package/dist/tools/tasks/create_and_submit_purchase_order.d.ts.map +1 -0
  229. package/dist/tools/tasks/create_and_submit_purchase_order.js +142 -0
  230. package/dist/tools/tasks/create_and_submit_purchase_order.js.map +1 -0
  231. package/dist/tools/tasks/find_product_by_sku.d.ts +4 -0
  232. package/dist/tools/tasks/find_product_by_sku.d.ts.map +1 -0
  233. package/dist/tools/tasks/find_product_by_sku.js +68 -0
  234. package/dist/tools/tasks/find_product_by_sku.js.map +1 -0
  235. package/dist/tools/tasks/fulfill_order.d.ts +4 -0
  236. package/dist/tools/tasks/fulfill_order.d.ts.map +1 -0
  237. package/dist/tools/tasks/fulfill_order.js +121 -0
  238. package/dist/tools/tasks/fulfill_order.js.map +1 -0
  239. package/dist/tools/tasks/get_inventory_across_warehouses.d.ts +4 -0
  240. package/dist/tools/tasks/get_inventory_across_warehouses.d.ts.map +1 -0
  241. package/dist/tools/tasks/get_inventory_across_warehouses.js +118 -0
  242. package/dist/tools/tasks/get_inventory_across_warehouses.js.map +1 -0
  243. package/dist/tools/tasks/index.d.ts +14 -0
  244. package/dist/tools/tasks/index.d.ts.map +1 -0
  245. package/dist/tools/tasks/index.js +32 -0
  246. package/dist/tools/tasks/index.js.map +1 -0
  247. package/dist/tools/tasks/publish_product_to_channels.d.ts +4 -0
  248. package/dist/tools/tasks/publish_product_to_channels.d.ts.map +1 -0
  249. package/dist/tools/tasks/publish_product_to_channels.js +109 -0
  250. package/dist/tools/tasks/publish_product_to_channels.js.map +1 -0
  251. package/dist/tools/tasks/reply_to_buyer_message.d.ts +4 -0
  252. package/dist/tools/tasks/reply_to_buyer_message.d.ts.map +1 -0
  253. package/dist/tools/tasks/reply_to_buyer_message.js +72 -0
  254. package/dist/tools/tasks/reply_to_buyer_message.js.map +1 -0
  255. package/dist/tools/tasks/reprice_listing.d.ts +4 -0
  256. package/dist/tools/tasks/reprice_listing.d.ts.map +1 -0
  257. package/dist/tools/tasks/reprice_listing.js +74 -0
  258. package/dist/tools/tasks/reprice_listing.js.map +1 -0
  259. package/dist/transports/stdio.d.ts +12 -0
  260. package/dist/transports/stdio.d.ts.map +1 -0
  261. package/dist/transports/stdio.js +30 -0
  262. package/dist/transports/stdio.js.map +1 -0
  263. package/dist/transports/streamableHttp.d.ts +33 -0
  264. package/dist/transports/streamableHttp.d.ts.map +1 -0
  265. package/dist/transports/streamableHttp.js +237 -0
  266. package/dist/transports/streamableHttp.js.map +1 -0
  267. package/package.json +47 -0
  268. package/vendor/openapi.snapshot.json +19887 -0
@@ -0,0 +1,104 @@
1
+ // =============================================================================
2
+ // src/server/buildServer.ts
3
+ // Wave: W6 — Stream C
4
+ //
5
+ // Constructs an `@modelcontextprotocol/sdk` `Server` configured with the
6
+ // dispatcher + provided tool list. The server returned here is *unconnected* —
7
+ // callers (transports/stdio.ts, transports/streamableHttp.ts) call
8
+ // `server.connect(t)` to bind a transport. For Streamable HTTP this is called
9
+ // once per session via the index.ts `makeServer` factory.
10
+ //
11
+ // Why this is split from index.ts: tests need to stand up a server with a
12
+ // fake `client` and assert dispatcher behavior in isolation, without booting
13
+ // stdio/SSE.
14
+ // =============================================================================
15
+ import { readFileSync } from "node:fs";
16
+ import { dirname, join } from "node:path";
17
+ import { fileURLToPath } from "node:url";
18
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
19
+ import { registerTools } from "./dispatcher.js";
20
+ /**
21
+ * Project the full session auth context down to the subset tools may read.
22
+ * Deliberately DROPS the raw bearer token — tool handlers never need it (the
23
+ * SDK client already carries it) and must not be able to exfiltrate it.
24
+ */
25
+ function toToolAuthInfo(auth) {
26
+ if (!auth)
27
+ return { mode: "apiKey", scopes: [] };
28
+ return {
29
+ mode: auth.mode,
30
+ ...(auth.companyId !== undefined ? { companyId: auth.companyId } : {}),
31
+ ...(auth.installId !== undefined ? { installId: auth.installId } : {}),
32
+ scopes: auth.scopes,
33
+ ...(auth.introspectionDegraded ? { introspectionDegraded: true } : {}),
34
+ };
35
+ }
36
+ export const SERVER_NAME = "@solidcommerce/mcp-server";
37
+ /**
38
+ * Read the package.json sibling to dist/index.js (or src/index.js under tsx).
39
+ * We resolve relative to this module rather than `process.cwd()` so the
40
+ * version stays correct when the binary is launched from any directory.
41
+ *
42
+ * Defensive fallback: if package.json is unreadable (extremely unusual —
43
+ * would mean the install is broken), we ship a clearly-labelled
44
+ * `0.0.0-unknown` so the server still boots.
45
+ */
46
+ function readPackageVersion() {
47
+ try {
48
+ // src/server/buildServer.ts → ../../package.json
49
+ // dist/server/buildServer.js → ../../package.json (same relative depth)
50
+ const here = dirname(fileURLToPath(import.meta.url));
51
+ const pkgPath = join(here, "..", "..", "package.json");
52
+ const raw = readFileSync(pkgPath, "utf8");
53
+ const parsed = JSON.parse(raw);
54
+ if (typeof parsed.version === "string" && parsed.version.length > 0) {
55
+ return parsed.version;
56
+ }
57
+ }
58
+ catch {
59
+ // fall through
60
+ }
61
+ return "0.0.0-unknown";
62
+ }
63
+ /**
64
+ * Wire a fully-configured MCP `Server`. Caller is responsible for `connect()`.
65
+ *
66
+ * The dispatcher's `ctxFactory` is closed over `client` + `setCurrentToolName`
67
+ * so each tool invocation:
68
+ *
69
+ * 1. Sets the audit ref to the tool name.
70
+ * 2. Receives a ToolContext { client, toolName }.
71
+ * 3. The SDK fires onRequest hooks → audit headers go on the wire.
72
+ * 4. After tool.handle resolves (or throws), the ref is cleared.
73
+ */
74
+ export function buildMcpServer(opts) {
75
+ const version = opts.version ?? readPackageVersion();
76
+ const server = new Server({ name: SERVER_NAME, version }, {
77
+ // We advertise tools support; resources/prompts/sampling come in later
78
+ // waves (W8+). Empty `tools: {}` is the canonical "we have tools" flag
79
+ // per the MCP spec; the actual list is served by tools/list.
80
+ capabilities: { tools: {} },
81
+ });
82
+ const auth = toToolAuthInfo(opts.auth);
83
+ const ctxFactory = (toolName) => {
84
+ // Set the ref BEFORE returning the context — the very next thing the
85
+ // dispatcher does is call `tool.handle(args, ctx)`, and that handler
86
+ // is what triggers SDK requests + onRequest hooks.
87
+ opts.setCurrentToolName(toolName);
88
+ return { client: opts.client, toolName, auth };
89
+ };
90
+ registerTools(server, opts.tools, ctxFactory);
91
+ // Best-effort: clear the ref whenever the transport closes. With per-session
92
+ // Server instances (E-A1) each Streamable HTTP session has its own ref, but
93
+ // stdio reuses one Server for the process lifetime, so clearing on close
94
+ // still prevents a stale tool name leaking across a reconnect.
95
+ const originalOnClose = server.onclose;
96
+ server.onclose = () => {
97
+ opts.setCurrentToolName(null);
98
+ if (typeof originalOnClose === "function") {
99
+ originalOnClose();
100
+ }
101
+ };
102
+ return server;
103
+ }
104
+ //# sourceMappingURL=buildServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildServer.js","sourceRoot":"","sources":["../../src/server/buildServer.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4BAA4B;AAC5B,sBAAsB;AACtB,EAAE;AACF,yEAAyE;AACzE,+EAA+E;AAC/E,mEAAmE;AACnE,8EAA8E;AAC9E,0DAA0D;AAC1D,EAAE;AACF,0EAA0E;AAC1E,6EAA6E;AAC7E,aAAa;AACb,gFAAgF;AAEhF,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGnE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhD;;;;GAIG;AACH,SAAS,cAAc,CAAC,IAAoC;IAC1D,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACjD,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,2BAA2B,CAAC;AAEvD;;;;;;;;GAQG;AACH,SAAS,kBAAkB;IACzB,IAAI,CAAC;QACH,iDAAiD;QACjD,wEAAwE;QACxE,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAC;QACxD,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAoBD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,IAAwB;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,kBAAkB,EAAE,CAAC;IAErD,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,EAC9B;QACE,uEAAuE;QACvE,uEAAuE;QACvE,6DAA6D;QAC7D,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;KAC5B,CACF,CAAC;IAEF,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,CAAC,QAAgB,EAAe,EAAE;QACnD,qEAAqE;QACrE,qEAAqE;QACrE,mDAAmD;QACnD,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACjD,CAAC,CAAC;IAEF,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAE9C,6EAA6E;IAC7E,4EAA4E;IAC5E,yEAAyE;IACzE,+DAA+D;IAC/D,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC;IACvC,MAAM,CAAC,OAAO,GAAG,GAAS,EAAE;QAC1B,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,OAAO,eAAe,KAAK,UAAU,EAAE,CAAC;YAC1C,eAAe,EAAE,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import type { ToolContext, ToolModule } from "../tools/contract.js";
3
+ export interface ContextFactory {
4
+ (toolName: string): ToolContext;
5
+ }
6
+ /**
7
+ * Register `tools/list` and `tools/call` handlers on the MCP server.
8
+ *
9
+ * The dispatcher does NOT attach audit hooks; that's the job of the caller
10
+ * (index.ts) wiring `attachAuditHook(client)` and threading the resulting
11
+ * `setCurrentToolName` into `ctxFactory`.
12
+ */
13
+ export declare function registerTools(server: Server, tools: ReadonlyArray<ToolModule>, ctxFactory: ContextFactory): void;
14
+ //# sourceMappingURL=dispatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/server/dispatcher.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAOxE,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EAGX,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,cAAc;IAC7B,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAAC;CACjC;AA0FD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,EAChC,UAAU,EAAE,cAAc,GACzB,IAAI,CAyFN"}
@@ -0,0 +1,190 @@
1
+ // =============================================================================
2
+ // src/server/dispatcher.ts
3
+ // Wave: W6 — Stream C
4
+ //
5
+ // Wires `ToolModule` instances onto an MCP `Server` via `setRequestHandler`
6
+ // for `tools/list` and `tools/call`.
7
+ //
8
+ // Why direct setRequestHandler over the higher-level MCP `tool()` ergonomics:
9
+ //
10
+ // 1. SDK 1.0.4's `Server` class is the documented low-level API (the
11
+ // newer `McpServer` helper landed in 1.4+ and we're pinned to 1.0.4 to
12
+ // match Claude Desktop's bundled SDK).
13
+ // 2. We need full control over the response envelope so we can surface
14
+ // `isError: true` + structured `required_scope` for the LLM scope-denied
15
+ // path. The high-level helper auto-serializes thrown errors into a flat
16
+ // text block which would lose structure.
17
+ //
18
+ // Flow per tools/call:
19
+ // 1. Resolve the tool by name. Unknown name → `{ isError: true }` with a
20
+ // hint (do NOT throw — the SDK turns thrown errors into JSON-RPC errors,
21
+ // and we want the LLM to *see* the failure as a regular tool result).
22
+ // 2. Parse args via the tool's Zod schema. Validation failure → structured
23
+ // `invalid_request` ToolResult.
24
+ // 3. Call ctxFactory(toolName) → ToolContext, then tool.handle(args, ctx).
25
+ // 4. Serialize ToolResult.content into MCP TextContent blocks. JSON entries
26
+ // are pretty-printed with 2-space indent so logs (and human eyes during
27
+ // debugging) stay readable.
28
+ // 5. Propagate isError through the wire response.
29
+ // =============================================================================
30
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
31
+ import { zodToJsonSchema } from "zod-to-json-schema";
32
+ /**
33
+ * Convert a `ToolResultContent[]` into MCP wire `TextContent` blocks. JSON
34
+ * entries are stringified with 2-space indent. Text entries are passed through.
35
+ *
36
+ * The MCP wire content shape for tools is `{ type: "text", text: string }`
37
+ * (plus newer `image`/`resource` variants we don't use here).
38
+ */
39
+ function serializeContent(content) {
40
+ return content.map((c) => {
41
+ if (c.type === "text") {
42
+ return { type: "text", text: c.text };
43
+ }
44
+ return { type: "text", text: JSON.stringify(c.json, null, 2) };
45
+ });
46
+ }
47
+ /**
48
+ * Build an MCP-shape error result without invoking the tool. Used for
49
+ * unknown-tool and arg-validation paths.
50
+ */
51
+ function buildClientErrorResult(errorType, message, extra = {}) {
52
+ return {
53
+ content: [
54
+ {
55
+ type: "json",
56
+ json: { error: { type: errorType, message, ...extra } },
57
+ },
58
+ ],
59
+ isError: true,
60
+ structuredError: { type: errorType, message },
61
+ };
62
+ }
63
+ /**
64
+ * Convert a Zod schema to JSON Schema for the MCP `tools/list` response.
65
+ *
66
+ * MCP requires `inputSchema` to be a JSON Schema object with `type: "object"`
67
+ * at the root. `zod-to-json-schema` emits `$schema` + `definitions` keys we
68
+ * don't want on the wire — strip them. If a tool's schema isn't an object
69
+ * (e.g., `z.array(...)`), we wrap it under a single `value` property; this
70
+ * shouldn't happen in practice (every ToolModule takes a named-arg object),
71
+ * but we'd rather degrade gracefully than crash tools/list.
72
+ */
73
+ function zodToMcpInputSchema(schema) {
74
+ // We intentionally accept ZodTypeAny but treat it loosely so we don't pull in
75
+ // the full zod-to-json-schema generic surface; the upstream types are
76
+ // permissive enough that ts-strict compilation here would require @ts-expect.
77
+ const raw = zodToJsonSchema(schema, {
78
+ target: "jsonSchema7",
79
+ $refStrategy: "none",
80
+ });
81
+ // Strip MCP-irrelevant top-level keys.
82
+ delete raw["$schema"];
83
+ delete raw["definitions"];
84
+ if (raw["type"] === "object") {
85
+ const out = {
86
+ type: "object",
87
+ };
88
+ if (raw["properties"] && typeof raw["properties"] === "object") {
89
+ out.properties = raw["properties"];
90
+ }
91
+ if (Array.isArray(raw["required"])) {
92
+ out.required = raw["required"];
93
+ }
94
+ return out;
95
+ }
96
+ // Fallback: wrap non-object schemas. See doc comment above.
97
+ return {
98
+ type: "object",
99
+ properties: { value: raw },
100
+ required: ["value"],
101
+ };
102
+ }
103
+ /**
104
+ * Register `tools/list` and `tools/call` handlers on the MCP server.
105
+ *
106
+ * The dispatcher does NOT attach audit hooks; that's the job of the caller
107
+ * (index.ts) wiring `attachAuditHook(client)` and threading the resulting
108
+ * `setCurrentToolName` into `ctxFactory`.
109
+ */
110
+ export function registerTools(server, tools, ctxFactory) {
111
+ // Index for O(1) lookup; rejecting duplicates upfront is friendlier than
112
+ // letting the second registration silently shadow the first.
113
+ const byName = new Map();
114
+ for (const tool of tools) {
115
+ if (byName.has(tool.name)) {
116
+ throw new Error(`duplicate tool name: ${tool.name}`);
117
+ }
118
+ byName.set(tool.name, tool);
119
+ }
120
+ // tools/list — emit each tool's name, description, JSON-schema'd args, and
121
+ // the Claude UI annotations object. The `required_scope` field is documented
122
+ // in the description so the LLM can see it inline (the MCP spec doesn't
123
+ // define a top-level scope field).
124
+ //
125
+ // `annotations.readOnlyHint` / `.destructiveHint` is the March 2025 MCP-spec
126
+ // addition Claude UI requires for Connectors Directory listing. We surface
127
+ // exactly one per tool (mutually exclusive — enforced by
128
+ // test/tools/annotations.test.ts). Hosts that ignore the field degrade
129
+ // safely; hosts that require it (Claude UI) get a green lint pass.
130
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
131
+ const list = tools.map((tool) => {
132
+ const annotations = {};
133
+ if (tool.readOnlyHint === true)
134
+ annotations.readOnlyHint = true;
135
+ if (tool.destructiveHint === true)
136
+ annotations.destructiveHint = true;
137
+ return {
138
+ name: tool.name,
139
+ description: `${tool.description}\n\nRequired scope: \`${tool.required_scope}\``,
140
+ inputSchema: zodToMcpInputSchema(tool.inputSchema),
141
+ annotations,
142
+ };
143
+ });
144
+ return { tools: list };
145
+ });
146
+ // tools/call — dispatch to the resolved ToolModule.
147
+ server.setRequestHandler(CallToolRequestSchema, async (req) => {
148
+ const { name, arguments: rawArgs } = req.params;
149
+ const tool = byName.get(name);
150
+ if (!tool) {
151
+ const err = buildClientErrorResult("not_found", `Unknown tool: ${name}`, { tool_name: name });
152
+ return {
153
+ content: serializeContent(err.content),
154
+ isError: true,
155
+ };
156
+ }
157
+ // Validate args. Zod's `safeParse` lets us return a structured error
158
+ // instead of letting a thrown ZodError bubble into the SDK's generic
159
+ // error path.
160
+ const parsed = tool.inputSchema.safeParse(rawArgs ?? {});
161
+ if (!parsed.success) {
162
+ const err = buildClientErrorResult("invalid_request", `Invalid arguments for tool ${name}`, { issues: parsed.error.issues });
163
+ return {
164
+ content: serializeContent(err.content),
165
+ isError: true,
166
+ };
167
+ }
168
+ let result;
169
+ try {
170
+ const ctx = ctxFactory(name);
171
+ result = await tool.handle(parsed.data, ctx);
172
+ }
173
+ catch (err) {
174
+ // Defense in depth: every well-behaved ToolModule.handle returns a
175
+ // ToolResult, even for errors (see contract.ts → mapSdkErrorToToolResult).
176
+ // But if a tool *does* throw, we still want a structured response.
177
+ const message = err instanceof Error ? err.message : String(err);
178
+ const fallback = buildClientErrorResult("server_error", message);
179
+ return {
180
+ content: serializeContent(fallback.content),
181
+ isError: true,
182
+ };
183
+ }
184
+ return {
185
+ content: serializeContent(result.content),
186
+ ...(result.isError ? { isError: true } : {}),
187
+ };
188
+ });
189
+ }
190
+ //# sourceMappingURL=dispatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/server/dispatcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { SessionAuthContext } from "./auth/oauth.js";
2
+ import type { McpHostName } from "./telemetry/hostName.js";
3
+ export interface SessionContext {
4
+ /** Resolved per-user OAuth / apiKey identity (E-A3). */
5
+ readonly auth: SessionAuthContext;
6
+ /** Canonical calling surface for per-surface telemetry (E-A4). */
7
+ readonly hostName: McpHostName;
8
+ }
9
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;CAChC"}
@@ -0,0 +1,11 @@
1
+ // =============================================================================
2
+ // src/session.ts
3
+ // Phase 0 / E-A3 + E-A4 — the per-session identity bundle.
4
+ //
5
+ // One SessionContext is resolved at `initialize` and bound to the session's
6
+ // dedicated MCP Server: the auth identity (E-A3) and the calling host surface
7
+ // (E-A4). Future per-session concerns (E-A5 rate-limit budget, etc.) attach
8
+ // here rather than widening every factory signature.
9
+ // =============================================================================
10
+ export {};
11
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,iBAAiB;AACjB,2DAA2D;AAC3D,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,4EAA4E;AAC5E,qDAAqD;AACrD,gFAAgF"}
@@ -0,0 +1,26 @@
1
+ /** Canonical surface ids (mirror docs/use_cases.md §7 telemetry NFR). */
2
+ export declare const MCP_HOST_NAMES: readonly ["claude_code", "claude_ui", "codex_cli", "chatgpt_ui", "gemini_ui", "gemini_cli", "m365_copilot", "grok_cli"];
3
+ export type McpHostName = (typeof MCP_HOST_NAMES)[number] | "unknown";
4
+ export declare const MCP_HOST_UNKNOWN = "unknown";
5
+ /** Force a fixed host id (single-host deployments / tests). Wins over detection. */
6
+ export declare const ENV_HOST_NAME_OVERRIDE = "SC_MCP_HOST_NAME";
7
+ export interface HostNameSignals {
8
+ /** MCP `initialize` params.clientInfo.name. */
9
+ readonly clientInfoName?: string | undefined;
10
+ /** HTTP `User-Agent` header. */
11
+ readonly userAgent?: string | undefined;
12
+ /** Env override (SC_MCP_HOST_NAME). Wins when set. */
13
+ readonly override?: string | undefined;
14
+ }
15
+ /**
16
+ * Map host signals to a canonical surface id. Override wins; otherwise the
17
+ * first matching pattern across (clientInfoName + userAgent); else `unknown`.
18
+ * Never throws.
19
+ */
20
+ export declare function resolveHostName(signals: HostNameSignals): McpHostName;
21
+ /**
22
+ * Defensively pull `params.clientInfo.name` out of a parsed MCP `initialize`
23
+ * request body. Returns undefined for any shape mismatch — never throws.
24
+ */
25
+ export declare function extractClientInfoName(body: unknown): string | undefined;
26
+ //# sourceMappingURL=hostName.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostName.d.ts","sourceRoot":"","sources":["../../src/telemetry/hostName.ts"],"names":[],"mappings":"AAeA,yEAAyE;AACzE,eAAO,MAAM,cAAc,yHASjB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;AAEtE,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAE1C,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AAezD,MAAM,WAAW,eAAe;IAC9B,+CAA+C;IAC/C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,gCAAgC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,WAAW,CAkBrE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQvE"}
@@ -0,0 +1,80 @@
1
+ // =============================================================================
2
+ // src/telemetry/hostName.ts
3
+ // Phase 0 / Item E-A4 — per-surface telemetry: resolve the calling AI host.
4
+ //
5
+ // Every one of the 8 distribution surfaces hits the SAME hosted MCP URL, so we
6
+ // attribute traffic by the MCP `clientInfo.name` sent in the `initialize`
7
+ // request (the canonical, host-controlled identity), with the HTTP User-Agent
8
+ // as a secondary signal and an env override as an escape hatch.
9
+ //
10
+ // This is BEST-EFFORT telemetry, NOT a security control: a client can spoof its
11
+ // name. Reliable attribution comes from pairing this with the server-minted
12
+ // `install_id` (E-A3). The audit hook stamps both; the KQL dashboard pivots on
13
+ // `mcp_host_name`.
14
+ // =============================================================================
15
+ /** Canonical surface ids (mirror docs/use_cases.md §7 telemetry NFR). */
16
+ export const MCP_HOST_NAMES = [
17
+ "claude_code",
18
+ "claude_ui",
19
+ "codex_cli",
20
+ "chatgpt_ui",
21
+ "gemini_ui",
22
+ "gemini_cli",
23
+ "m365_copilot",
24
+ "grok_cli",
25
+ ];
26
+ export const MCP_HOST_UNKNOWN = "unknown";
27
+ /** Force a fixed host id (single-host deployments / tests). Wins over detection. */
28
+ export const ENV_HOST_NAME_OVERRIDE = "SC_MCP_HOST_NAME";
29
+ // Order matters — most specific first. `claude-code` must precede the `claude`
30
+ // catch-all; `gemini-cli` must precede `gemini`.
31
+ const HOST_PATTERNS = [
32
+ [/claude[-_ ]?code/i, "claude_code"],
33
+ [/codex/i, "codex_cli"],
34
+ [/chatgpt|openai/i, "chatgpt_ui"],
35
+ [/gemini[-_ ]?cli/i, "gemini_cli"],
36
+ [/gemini|vertex/i, "gemini_ui"],
37
+ [/copilot|m365|microsoft[-_ ]?365|teams/i, "m365_copilot"],
38
+ [/grok|xai/i, "grok_cli"],
39
+ [/claude|anthropic/i, "claude_ui"], // catch-all AFTER claude-code
40
+ ];
41
+ /**
42
+ * Map host signals to a canonical surface id. Override wins; otherwise the
43
+ * first matching pattern across (clientInfoName + userAgent); else `unknown`.
44
+ * Never throws.
45
+ */
46
+ export function resolveHostName(signals) {
47
+ const override = signals.override?.trim();
48
+ if (override && override.length > 0) {
49
+ // Accept a known canonical id verbatim; otherwise still honor the operator's
50
+ // explicit string by returning it (cast) — telemetry, not a closed enum gate.
51
+ return override;
52
+ }
53
+ const haystack = [signals.clientInfoName, signals.userAgent]
54
+ .filter((s) => typeof s === "string" && s.length > 0)
55
+ .join(" ");
56
+ if (haystack.length === 0)
57
+ return MCP_HOST_UNKNOWN;
58
+ for (const [pattern, name] of HOST_PATTERNS) {
59
+ if (pattern.test(haystack))
60
+ return name;
61
+ }
62
+ return MCP_HOST_UNKNOWN;
63
+ }
64
+ /**
65
+ * Defensively pull `params.clientInfo.name` out of a parsed MCP `initialize`
66
+ * request body. Returns undefined for any shape mismatch — never throws.
67
+ */
68
+ export function extractClientInfoName(body) {
69
+ if (body === null || typeof body !== "object")
70
+ return undefined;
71
+ const params = body.params;
72
+ if (params === null || typeof params !== "object")
73
+ return undefined;
74
+ const clientInfo = params.clientInfo;
75
+ if (clientInfo === null || typeof clientInfo !== "object")
76
+ return undefined;
77
+ const name = clientInfo.name;
78
+ return typeof name === "string" && name.length > 0 ? name : undefined;
79
+ }
80
+ //# sourceMappingURL=hostName.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostName.js","sourceRoot":"","sources":["../../src/telemetry/hostName.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4BAA4B;AAC5B,4EAA4E;AAC5E,EAAE;AACF,+EAA+E;AAC/E,0EAA0E;AAC1E,8EAA8E;AAC9E,gEAAgE;AAChE,EAAE;AACF,gFAAgF;AAChF,4EAA4E;AAC5E,+EAA+E;AAC/E,mBAAmB;AACnB,gFAAgF;AAEhF,yEAAyE;AACzE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,aAAa;IACb,WAAW;IACX,WAAW;IACX,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,cAAc;IACd,UAAU;CACF,CAAC;AAIX,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAS,CAAC;AAE1C,oFAAoF;AACpF,MAAM,CAAC,MAAM,sBAAsB,GAAG,kBAAkB,CAAC;AAEzD,+EAA+E;AAC/E,iDAAiD;AACjD,MAAM,aAAa,GAAkD;IACnE,CAAC,mBAAmB,EAAE,aAAa,CAAC;IACpC,CAAC,QAAQ,EAAE,WAAW,CAAC;IACvB,CAAC,iBAAiB,EAAE,YAAY,CAAC;IACjC,CAAC,kBAAkB,EAAE,YAAY,CAAC;IAClC,CAAC,gBAAgB,EAAE,WAAW,CAAC;IAC/B,CAAC,wCAAwC,EAAE,cAAc,CAAC;IAC1D,CAAC,WAAW,EAAE,UAAU,CAAC;IACzB,CAAC,mBAAmB,EAAE,WAAW,CAAC,EAAE,8BAA8B;CACnE,CAAC;AAWF;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,OAAwB;IACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1C,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,6EAA6E;QAC7E,8EAA8E;QAC9E,OAAO,QAAuB,CAAC;IACjC,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,SAAS,CAAC;SACzD,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SACjE,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,gBAAgB,CAAC;IAEnD,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,aAAa,EAAE,CAAC;QAC5C,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;IAC1C,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAa;IACjD,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChE,MAAM,MAAM,GAAI,IAA6B,CAAC,MAAM,CAAC;IACrD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACpE,MAAM,UAAU,GAAI,MAAmC,CAAC,UAAU,CAAC;IACnE,IAAI,UAAU,KAAK,IAAI,IAAI,OAAO,UAAU,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC5E,MAAM,IAAI,GAAI,UAAiC,CAAC,IAAI,CAAC;IACrD,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACxE,CAAC"}
@@ -0,0 +1,125 @@
1
+ import type { SolidCommerceClient } from "@solidcommerce/sdk";
2
+ import type { ZodTypeAny } from "zod";
3
+ /** Foundation = OpenAPI-derived; Task = hand-authored composition. */
4
+ export type ToolKind = "foundation" | "task";
5
+ /**
6
+ * Resolved auth identity for the current MCP session (Phase 0 / E-A3).
7
+ * Populated by the per-session server factory from either a per-user OAuth
8
+ * bearer token (remote hosts) or the env API key (stdio / Scotty / internal).
9
+ */
10
+ export interface ToolAuthInfo {
11
+ /** `oauth` = per-user bearer; `apiKey` = service-to-service env key. */
12
+ readonly mode: "oauth" | "apiKey";
13
+ /** Company the token is scoped to, when introspection surfaced it. */
14
+ readonly companyId?: string;
15
+ /** Per-(host, company) install id minted at OAuth consent. */
16
+ readonly installId?: string;
17
+ /** Granted scopes (empty for apiKey / when not surfaced). */
18
+ readonly scopes: ReadonlyArray<string>;
19
+ /**
20
+ * True when introspection could not verify the token (Auth outage / circuit
21
+ * open) and we forwarded it unverified — Platform remains the authority.
22
+ */
23
+ readonly introspectionDegraded?: boolean;
24
+ }
25
+ /** Provided to every tool handler. The client is already auth-injected. */
26
+ export interface ToolContext {
27
+ /** Fully configured SDK client with audit hooks pre-installed. */
28
+ readonly client: SolidCommerceClient;
29
+ /** The MCP tool name being dispatched (for logging / audit headers). */
30
+ readonly toolName: string;
31
+ /**
32
+ * Resolved session auth identity. Optional so existing unit tests that build
33
+ * a bare context still compile; the dispatcher always populates it in
34
+ * production (see server/buildServer.ts).
35
+ */
36
+ readonly auth?: ToolAuthInfo;
37
+ }
38
+ /**
39
+ * MCP wire content. We deliberately accept both text + json — the
40
+ * MCP TypeScript SDK serializes both into its `TextContent` shape,
41
+ * with JSON values pretty-printed.
42
+ */
43
+ export type ToolResultContent = {
44
+ readonly type: "text";
45
+ readonly text: string;
46
+ } | {
47
+ readonly type: "json";
48
+ readonly json: unknown;
49
+ };
50
+ /**
51
+ * Structured error payload exposed to the LLM when an SDK call fails.
52
+ * Carrying `required_scope` distinct from the human message lets the LLM
53
+ * surface "you need scope X" cleanly without parsing English.
54
+ */
55
+ export interface StructuredError {
56
+ readonly type: string;
57
+ readonly code?: string;
58
+ readonly required_scope?: string;
59
+ readonly retry_after?: number;
60
+ readonly request_id?: string;
61
+ readonly message?: string;
62
+ }
63
+ export interface ToolResult {
64
+ readonly content: ReadonlyArray<ToolResultContent>;
65
+ readonly isError?: boolean;
66
+ readonly structuredError?: StructuredError;
67
+ }
68
+ /**
69
+ * One MCP tool. Foundation tools are auto-emitted by the generator;
70
+ * task tools are hand-authored.
71
+ *
72
+ * `inputSchema` is a Zod schema — Stream C converts it to JSON Schema for
73
+ * the MCP `tools/list` response (the MCP SDK accepts JSON Schema, and Zod
74
+ * provides `z.toJSONSchema(...)` ergonomics in v3+).
75
+ */
76
+ export interface ToolModule {
77
+ readonly name: string;
78
+ readonly kind: ToolKind;
79
+ readonly description: string;
80
+ readonly required_scope: string;
81
+ readonly inputSchema: ZodTypeAny;
82
+ readonly handle: (args: unknown, ctx: ToolContext) => Promise<ToolResult>;
83
+ /**
84
+ * Claude UI Connectors Directory submission requirement (March 2025 MCP spec):
85
+ * every tool MUST advertise exactly one of `readOnlyHint` or `destructiveHint`.
86
+ * Foundation tools derive this from HTTP method (GET → readOnly, write verbs →
87
+ * destructive). Task tools must set it manually — natural language can mislead
88
+ * (e.g. `publish_product_to_channels` is destructive even though "publish"
89
+ * reads neutrally). Enforced by `test/tools/annotations.test.ts`.
90
+ *
91
+ * Mutually exclusive: setting both is a build-time error.
92
+ */
93
+ readonly readOnlyHint?: boolean;
94
+ readonly destructiveHint?: boolean;
95
+ }
96
+ /**
97
+ * Map a thrown SDK error into a structured ToolResult. Used by the
98
+ * dispatcher (Stream C) AND by task tools (Stream B) when they catch
99
+ * partial failures and want to fold them into the result.
100
+ *
101
+ * Accepts three input shapes:
102
+ *
103
+ * 1. A typed `ApiError` (or duck-typed equivalent) with camelCase fields
104
+ * (`requiredScope`, `requestId`, `retryAfter`). This is what the SDK's
105
+ * `unwrap()` / `mapErrorEnvelope()` produces.
106
+ *
107
+ * 2. The raw openapi-fetch `result.error` — the *parsed JSON body* of a
108
+ * 4xx/5xx response. Foundation tools call `client.raw.<METHOD>(...)`
109
+ * directly and forward `result.error` here without going through
110
+ * `unwrap()`. The body is shaped `{ error: { type, code, message,
111
+ * required_scope, retry_after, request_id, ... } }` (snake_case wire
112
+ * fields). We unwrap one layer if present.
113
+ *
114
+ * 3. Anything else (network-level errors, plain `Error`, etc.) — wrapped
115
+ * as `type: "transport"` so the LLM doesn't try to interpret a
116
+ * missing `required_scope`.
117
+ *
118
+ * Why the unwrap matters for W6 acceptance: §4 requires that scope-denied
119
+ * tool calls surface the `required_scope` field on the wire. Without the
120
+ * unwrap, foundation tools (which forward `result.error` from openapi-fetch)
121
+ * would emit `type: "transport"` and lose `required_scope` entirely. See
122
+ * test/e2e/inspector.test.ts and scripts/w6_smoke.sh probe A6.
123
+ */
124
+ export declare function mapSdkErrorToToolResult(err: unknown): ToolResult;
125
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/tools/contract.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,mBAAmB,EAAY,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEtC,sEAAsE;AACtE,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,MAAM,CAAC;AAE7C;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IAClC,sEAAsE;IACtE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACvC;;;OAGG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAC1C;AAED,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtD;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC;CAC5C;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1E;;;;;;;;;OASG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CA+DhE"}