@stackable-labs/mcp-app-extension 1.7.1 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -579,17 +579,18 @@ const result = await capabilities.data.fetch('https://api.example.com/orders', {
579
579
  > See [Instance Settings](./instance-settings) for the full schema-declaration + storage-mode story, including which field types accept \`secret: true\`.
580
580
 
581
581
  ## context.read \u2014 Read Platform Context
582
- Read framework-provided context (customer ID, email, extension settings, etc.).
582
+ Read framework-provided context (customer ID, email, messaging conversation, extension settings, etc.).
583
583
  - **Permission required:** \`context:read\`
584
584
  - **Usage:** \`capabilities.context.read(): Promise<ContextData>\`
585
- - **ContextData shape:** \`{ customerId?: string, customerEmail?: string, settings?: Record<string, unknown>, [key: string]: unknown }\`
585
+ - **ContextData shape:** \`{ customerId?: string, customerEmail?: string, messaging?: { conversationId?: string | null, appId?: string | null }, settings?: Record<string, unknown>, [key: string]: unknown }\`
586
586
  - **Convenience hooks:**
587
587
  - \`useContextData()\` returns \`ContextData & { loading: boolean }\`
588
588
  - \`useSettings()\` returns \`Record<string, unknown>\` \u2014 shorthand for \`contextData.settings ?? {}\`
589
589
 
590
590
  \`\`\`tsx
591
- // Read all context (customer + settings)
592
- const { loading, customerId, customerEmail, settings } = useContextData()
591
+ // Read all context (customer + messaging + settings)
592
+ const { loading, customerId, customerEmail, messaging, settings } = useContextData()
593
+ const conversationId = messaging?.conversationId
593
594
 
594
595
  // Read only extension settings (convenience)
595
596
  const settings = useSettings()
@@ -599,6 +600,9 @@ const apiBaseUrl = settings.baseUrl as string
599
600
  const context = await capabilities.context.read()
600
601
  \`\`\`
601
602
 
603
+ ### Messaging context
604
+ \`messaging.conversationId\` is the active Messaging conversation ID, or \`null\` until the widget has an open conversation. Use this when you need the ID for an API call from a non-event surface. If you're already reacting to a postback button click, prefer reading \`event.data.conversationId\` from \`useMessagingEvent\` \u2014 it doesn't require \`context:read\`.
605
+
602
606
  ### Extension settings in context
603
607
  Non-secret settings declared in \`settingsSchema\` are automatically available via \`contextData.settings\`. Values are scoped to the calling extension on the current instance \u2014 an extension never sees other extensions' settings.
604
608
 
@@ -621,7 +625,7 @@ Trigger framework-defined actions (e.g., open a new conversation, set conversati
621
625
  - **Permission required:** \`actions:invoke\`
622
626
  - **Usage:** \`capabilities.actions.invoke<T>(action: string, payload?: Record<string, unknown>): Promise<T>\`
623
627
  - **Available actions:**
624
- - \`'newConversation'\` \u2014 start a new Zendesk conversation (optionally with tags/fields)
628
+ - \`'newConversation'\` \u2014 start a new Messaging conversation (optionally with tags/fields)
625
629
  - \`'setConversationTags'\` \u2014 set tags on the current/next conversation
626
630
  - \`'setConversationFields'\` \u2014 set custom fields on the current/next conversation
627
631
  - \`'open'\` / \`'close'\` / \`'show'\` / \`'hide'\` \u2014 control the Zendesk messenger widget
@@ -1088,9 +1092,10 @@ const viewState = useStore(appStore, (s) => s.viewState)
1088
1092
  \`\`\`
1089
1093
 
1090
1094
  ## useContextData()
1091
- Reads host-provided context including extension settings. Returns \`{ loading, customerId, customerEmail, settings, ... }\`.
1095
+ Reads host-provided context including extension settings. Returns \`{ loading, customerId, customerEmail, messaging, settings, ... }\`. \`messaging.conversationId\` is the active Messaging conversation ID (or \`null\` until one exists).
1092
1096
  \`\`\`tsx
1093
- const { loading, customerId, customerEmail, settings } = useContextData()
1097
+ const { loading, customerId, customerEmail, messaging, settings } = useContextData()
1098
+ const conversationId = messaging?.conversationId
1094
1099
  \`\`\`
1095
1100
 
1096
1101
  ## useSettings()
@@ -2271,7 +2276,7 @@ Every domain your extension calls must be listed in \`allowedDomains\`:
2271
2276
  - The framework will reject requests to unlisted domains
2272
2277
  - Add each subdomain separately when listing exact hosts (e.g., \`api.example.com\` and \`cdn.example.com\`)
2273
2278
 
2274
- ### Wildcards
2279
+ #### Wildcard Domains
2275
2280
 
2276
2281
  **Prefer exact hostnames where possible.** Use \`*.example.com\` only when you
2277
2282
  need to match any subdomain \u2014 for example, tenant-per-subdomain platforms
@@ -3696,7 +3701,7 @@ Wire up a new capability in this extension. Follow these steps exactly:
3696
3701
  Ask which capability to add. Valid capabilities:
3697
3702
  - \`data.query\` \u2014 host-mediated data requests (action name + params \u2192 host returns data)
3698
3703
  - \`data.fetch\` \u2014 direct HTTP requests from the sandbox (requires allowedDomains)
3699
- - \`context.read\` \u2014 read host-provided context (customerId, customerEmail, etc.)
3704
+ - \`context.read\` \u2014 read host-provided context (customerId, customerEmail, messaging.conversationId, etc.)
3700
3705
  - \`actions.toast\` \u2014 show toast notifications (success, error, info, warning)
3701
3706
  - \`actions.invoke\` \u2014 invoke host actions (e.g., open new conversation)
3702
3707
  - \`extend:identity\` \u2014 enrich identity JWT claims before signing
@@ -4115,7 +4120,7 @@ var SKILLS = [
4115
4120
  },
4116
4121
  {
4117
4122
  id: "capabilities",
4118
- description: "Extension capabilities: data.query, data.fetch, context.read, actions.toast, actions.invoke. Use when wiring up host-mediated APIs or direct HTTP requests.",
4123
+ description: "Extension capabilities: data.query, data.fetch, context.read, actions.toast, actions.invoke. Use when wiring up platform-mediated APIs or direct HTTP requests.",
4119
4124
  type: "knowledge",
4120
4125
  content: () => generateCapabilities()
4121
4126
  },
@@ -4166,7 +4171,7 @@ var SKILLS = [
4166
4171
  },
4167
4172
  {
4168
4173
  id: "external-apis",
4169
- description: "Direct HTTP requests via data.fetch, allowedDomains configuration, and API wrapper patterns. Use when connecting an extension to external APIs.",
4174
+ description: "Direct HTTP requests via data.fetch \u2014 allowed domains (including wildcard subdomains like *.myshopify.com), allowedDomains configuration, API wrapper patterns, and data.fetch vs data.query. Use when connecting an extension to external APIs or configuring allowedDomains.",
4170
4175
  type: "knowledge",
4171
4176
  content: () => generateExternalApis()
4172
4177
  },
@@ -4178,7 +4183,7 @@ var SKILLS = [
4178
4183
  },
4179
4184
  {
4180
4185
  id: "styling-and-theming",
4181
- description: "Host theme inheritance, className usage, layout components, and CSS constraints. Use when styling extension UI or working with the host theme.",
4186
+ description: "Extension theming and styling - tailwind className usage, layout components, and CSS constraints. Use when styling extension UI or working with the host theme.",
4182
4187
  type: "knowledge",
4183
4188
  content: () => generateStylingAndTheming()
4184
4189
  },
@@ -4268,7 +4273,7 @@ var SKILLS = [
4268
4273
  },
4269
4274
  {
4270
4275
  id: "add-capability",
4271
- description: "Wire up a new capability (data.fetch, data.query, context.read, actions.toast, actions.invoke) in this extension. Use when adding a new host-mediated API.",
4276
+ description: "Wire up a new capability (data.fetch, data.query, context.read, actions.toast, actions.invoke) in this extension. Use when adding a new platform-mediated API.",
4272
4277
  type: "action",
4273
4278
  content: () => generateAddCapabilityCommand()
4274
4279
  },
package/dist/server.js CHANGED
@@ -572,17 +572,18 @@ const result = await capabilities.data.fetch('https://api.example.com/orders', {
572
572
  > See [Instance Settings](./instance-settings) for the full schema-declaration + storage-mode story, including which field types accept \`secret: true\`.
573
573
 
574
574
  ## context.read \u2014 Read Platform Context
575
- Read framework-provided context (customer ID, email, extension settings, etc.).
575
+ Read framework-provided context (customer ID, email, messaging conversation, extension settings, etc.).
576
576
  - **Permission required:** \`context:read\`
577
577
  - **Usage:** \`capabilities.context.read(): Promise<ContextData>\`
578
- - **ContextData shape:** \`{ customerId?: string, customerEmail?: string, settings?: Record<string, unknown>, [key: string]: unknown }\`
578
+ - **ContextData shape:** \`{ customerId?: string, customerEmail?: string, messaging?: { conversationId?: string | null, appId?: string | null }, settings?: Record<string, unknown>, [key: string]: unknown }\`
579
579
  - **Convenience hooks:**
580
580
  - \`useContextData()\` returns \`ContextData & { loading: boolean }\`
581
581
  - \`useSettings()\` returns \`Record<string, unknown>\` \u2014 shorthand for \`contextData.settings ?? {}\`
582
582
 
583
583
  \`\`\`tsx
584
- // Read all context (customer + settings)
585
- const { loading, customerId, customerEmail, settings } = useContextData()
584
+ // Read all context (customer + messaging + settings)
585
+ const { loading, customerId, customerEmail, messaging, settings } = useContextData()
586
+ const conversationId = messaging?.conversationId
586
587
 
587
588
  // Read only extension settings (convenience)
588
589
  const settings = useSettings()
@@ -592,6 +593,9 @@ const apiBaseUrl = settings.baseUrl as string
592
593
  const context = await capabilities.context.read()
593
594
  \`\`\`
594
595
 
596
+ ### Messaging context
597
+ \`messaging.conversationId\` is the active Messaging conversation ID, or \`null\` until the widget has an open conversation. Use this when you need the ID for an API call from a non-event surface. If you're already reacting to a postback button click, prefer reading \`event.data.conversationId\` from \`useMessagingEvent\` \u2014 it doesn't require \`context:read\`.
598
+
595
599
  ### Extension settings in context
596
600
  Non-secret settings declared in \`settingsSchema\` are automatically available via \`contextData.settings\`. Values are scoped to the calling extension on the current instance \u2014 an extension never sees other extensions' settings.
597
601
 
@@ -614,7 +618,7 @@ Trigger framework-defined actions (e.g., open a new conversation, set conversati
614
618
  - **Permission required:** \`actions:invoke\`
615
619
  - **Usage:** \`capabilities.actions.invoke<T>(action: string, payload?: Record<string, unknown>): Promise<T>\`
616
620
  - **Available actions:**
617
- - \`'newConversation'\` \u2014 start a new Zendesk conversation (optionally with tags/fields)
621
+ - \`'newConversation'\` \u2014 start a new Messaging conversation (optionally with tags/fields)
618
622
  - \`'setConversationTags'\` \u2014 set tags on the current/next conversation
619
623
  - \`'setConversationFields'\` \u2014 set custom fields on the current/next conversation
620
624
  - \`'open'\` / \`'close'\` / \`'show'\` / \`'hide'\` \u2014 control the Zendesk messenger widget
@@ -1081,9 +1085,10 @@ const viewState = useStore(appStore, (s) => s.viewState)
1081
1085
  \`\`\`
1082
1086
 
1083
1087
  ## useContextData()
1084
- Reads host-provided context including extension settings. Returns \`{ loading, customerId, customerEmail, settings, ... }\`.
1088
+ Reads host-provided context including extension settings. Returns \`{ loading, customerId, customerEmail, messaging, settings, ... }\`. \`messaging.conversationId\` is the active Messaging conversation ID (or \`null\` until one exists).
1085
1089
  \`\`\`tsx
1086
- const { loading, customerId, customerEmail, settings } = useContextData()
1090
+ const { loading, customerId, customerEmail, messaging, settings } = useContextData()
1091
+ const conversationId = messaging?.conversationId
1087
1092
  \`\`\`
1088
1093
 
1089
1094
  ## useSettings()
@@ -2264,7 +2269,7 @@ Every domain your extension calls must be listed in \`allowedDomains\`:
2264
2269
  - The framework will reject requests to unlisted domains
2265
2270
  - Add each subdomain separately when listing exact hosts (e.g., \`api.example.com\` and \`cdn.example.com\`)
2266
2271
 
2267
- ### Wildcards
2272
+ #### Wildcard Domains
2268
2273
 
2269
2274
  **Prefer exact hostnames where possible.** Use \`*.example.com\` only when you
2270
2275
  need to match any subdomain \u2014 for example, tenant-per-subdomain platforms
@@ -3689,7 +3694,7 @@ Wire up a new capability in this extension. Follow these steps exactly:
3689
3694
  Ask which capability to add. Valid capabilities:
3690
3695
  - \`data.query\` \u2014 host-mediated data requests (action name + params \u2192 host returns data)
3691
3696
  - \`data.fetch\` \u2014 direct HTTP requests from the sandbox (requires allowedDomains)
3692
- - \`context.read\` \u2014 read host-provided context (customerId, customerEmail, etc.)
3697
+ - \`context.read\` \u2014 read host-provided context (customerId, customerEmail, messaging.conversationId, etc.)
3693
3698
  - \`actions.toast\` \u2014 show toast notifications (success, error, info, warning)
3694
3699
  - \`actions.invoke\` \u2014 invoke host actions (e.g., open new conversation)
3695
3700
  - \`extend:identity\` \u2014 enrich identity JWT claims before signing
@@ -4108,7 +4113,7 @@ var SKILLS = [
4108
4113
  },
4109
4114
  {
4110
4115
  id: "capabilities",
4111
- description: "Extension capabilities: data.query, data.fetch, context.read, actions.toast, actions.invoke. Use when wiring up host-mediated APIs or direct HTTP requests.",
4116
+ description: "Extension capabilities: data.query, data.fetch, context.read, actions.toast, actions.invoke. Use when wiring up platform-mediated APIs or direct HTTP requests.",
4112
4117
  type: "knowledge",
4113
4118
  content: () => generateCapabilities()
4114
4119
  },
@@ -4159,7 +4164,7 @@ var SKILLS = [
4159
4164
  },
4160
4165
  {
4161
4166
  id: "external-apis",
4162
- description: "Direct HTTP requests via data.fetch, allowedDomains configuration, and API wrapper patterns. Use when connecting an extension to external APIs.",
4167
+ description: "Direct HTTP requests via data.fetch \u2014 allowed domains (including wildcard subdomains like *.myshopify.com), allowedDomains configuration, API wrapper patterns, and data.fetch vs data.query. Use when connecting an extension to external APIs or configuring allowedDomains.",
4163
4168
  type: "knowledge",
4164
4169
  content: () => generateExternalApis()
4165
4170
  },
@@ -4171,7 +4176,7 @@ var SKILLS = [
4171
4176
  },
4172
4177
  {
4173
4178
  id: "styling-and-theming",
4174
- description: "Host theme inheritance, className usage, layout components, and CSS constraints. Use when styling extension UI or working with the host theme.",
4179
+ description: "Extension theming and styling - tailwind className usage, layout components, and CSS constraints. Use when styling extension UI or working with the host theme.",
4175
4180
  type: "knowledge",
4176
4181
  content: () => generateStylingAndTheming()
4177
4182
  },
@@ -4261,7 +4266,7 @@ var SKILLS = [
4261
4266
  },
4262
4267
  {
4263
4268
  id: "add-capability",
4264
- description: "Wire up a new capability (data.fetch, data.query, context.read, actions.toast, actions.invoke) in this extension. Use when adding a new host-mediated API.",
4269
+ description: "Wire up a new capability (data.fetch, data.query, context.read, actions.toast, actions.invoke) in this extension. Use when adding a new platform-mediated API.",
4265
4270
  type: "action",
4266
4271
  content: () => generateAddCapabilityCommand()
4267
4272
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackable-labs/mcp-app-extension",
3
- "version": "1.7.1",
3
+ "version": "1.9.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mcp-app-extension": "./dist/index.js"