@clawpify/skills 1.0.1

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 (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -0
  3. package/clawpify/SKILL.md +134 -0
  4. package/clawpify/references/blogs.md +385 -0
  5. package/clawpify/references/bulk-operations.md +386 -0
  6. package/clawpify/references/collections.md +71 -0
  7. package/clawpify/references/customers.md +141 -0
  8. package/clawpify/references/discounts.md +431 -0
  9. package/clawpify/references/draft-orders.md +495 -0
  10. package/clawpify/references/files.md +355 -0
  11. package/clawpify/references/fulfillments.md +437 -0
  12. package/clawpify/references/gift-cards.md +453 -0
  13. package/clawpify/references/inventory.md +107 -0
  14. package/clawpify/references/locations.md +349 -0
  15. package/clawpify/references/marketing.md +352 -0
  16. package/clawpify/references/markets.md +346 -0
  17. package/clawpify/references/menus.md +313 -0
  18. package/clawpify/references/metafields.md +461 -0
  19. package/clawpify/references/orders.md +164 -0
  20. package/clawpify/references/pages.md +308 -0
  21. package/clawpify/references/products.md +277 -0
  22. package/clawpify/references/refunds.md +401 -0
  23. package/clawpify/references/segments.md +319 -0
  24. package/clawpify/references/shipping.md +406 -0
  25. package/clawpify/references/shop.md +307 -0
  26. package/clawpify/references/subscriptions.md +429 -0
  27. package/clawpify/references/translations.md +270 -0
  28. package/clawpify/references/webhooks.md +400 -0
  29. package/dist/agent.d.ts +18 -0
  30. package/dist/agent.d.ts.map +1 -0
  31. package/dist/agent.js +100 -0
  32. package/dist/auth.d.ts +34 -0
  33. package/dist/auth.d.ts.map +1 -0
  34. package/dist/auth.js +58 -0
  35. package/dist/index.d.ts +41 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +22 -0
  38. package/dist/mcp-server.d.ts +3 -0
  39. package/dist/mcp-server.d.ts.map +1 -0
  40. package/dist/mcp-server.js +236 -0
  41. package/dist/shopify.d.ts +29 -0
  42. package/dist/shopify.d.ts.map +1 -0
  43. package/dist/shopify.js +41 -0
  44. package/dist/skills.d.ts +8 -0
  45. package/dist/skills.d.ts.map +1 -0
  46. package/dist/skills.js +36 -0
  47. package/package.json +100 -0
  48. package/src/agent.ts +133 -0
  49. package/src/auth.ts +109 -0
  50. package/src/index.ts +55 -0
  51. package/src/mcp-server.ts +190 -0
  52. package/src/shopify.ts +63 -0
  53. package/src/skills.ts +42 -0
@@ -0,0 +1,400 @@
1
+ # Shopify Webhooks
2
+
3
+ Subscribe to event notifications via the GraphQL Admin API.
4
+
5
+ ## Overview
6
+
7
+ Webhooks push real-time notifications to your app when events occur in a Shopify store, eliminating the need for polling.
8
+
9
+ ## List Webhook Subscriptions
10
+
11
+ ```graphql
12
+ query ListWebhooks($first: Int!) {
13
+ webhookSubscriptions(first: $first) {
14
+ nodes {
15
+ id
16
+ topic
17
+ endpoint {
18
+ ... on WebhookHttpEndpoint {
19
+ callbackUrl
20
+ }
21
+ ... on WebhookPubSubEndpoint {
22
+ pubSubProject
23
+ pubSubTopic
24
+ }
25
+ ... on WebhookEventBridgeEndpoint {
26
+ arn
27
+ }
28
+ }
29
+ format
30
+ createdAt
31
+ }
32
+ }
33
+ }
34
+ ```
35
+ Variables: `{ "first": 50 }`
36
+
37
+ ## Get Webhook Subscription
38
+
39
+ ```graphql
40
+ query GetWebhook($id: ID!) {
41
+ webhookSubscription(id: $id) {
42
+ id
43
+ topic
44
+ endpoint {
45
+ ... on WebhookHttpEndpoint {
46
+ callbackUrl
47
+ }
48
+ }
49
+ format
50
+ includeFields
51
+ metafieldNamespaces
52
+ filter
53
+ createdAt
54
+ updatedAt
55
+ }
56
+ }
57
+ ```
58
+ Variables: `{ "id": "gid://shopify/WebhookSubscription/123" }`
59
+
60
+ ## Get Webhooks Count
61
+
62
+ ```graphql
63
+ query GetWebhooksCount {
64
+ webhookSubscriptionsCount {
65
+ count
66
+ }
67
+ }
68
+ ```
69
+
70
+ ## Create HTTP Webhook
71
+
72
+ ```graphql
73
+ mutation CreateWebhook($topic: WebhookSubscriptionTopic!, $webhookSubscription: WebhookSubscriptionInput!) {
74
+ webhookSubscriptionCreate(topic: $topic, webhookSubscription: $webhookSubscription) {
75
+ webhookSubscription {
76
+ id
77
+ topic
78
+ endpoint {
79
+ ... on WebhookHttpEndpoint {
80
+ callbackUrl
81
+ }
82
+ }
83
+ }
84
+ userErrors {
85
+ field
86
+ message
87
+ }
88
+ }
89
+ }
90
+ ```
91
+ Variables:
92
+ ```json
93
+ {
94
+ "topic": "ORDERS_CREATE",
95
+ "webhookSubscription": {
96
+ "callbackUrl": "https://myapp.example.com/webhooks/orders",
97
+ "format": "JSON"
98
+ }
99
+ }
100
+ ```
101
+
102
+ ## Create Webhook with Filters
103
+
104
+ ```graphql
105
+ mutation CreateFilteredWebhook($topic: WebhookSubscriptionTopic!, $webhookSubscription: WebhookSubscriptionInput!) {
106
+ webhookSubscriptionCreate(topic: $topic, webhookSubscription: $webhookSubscription) {
107
+ webhookSubscription {
108
+ id
109
+ topic
110
+ filter
111
+ }
112
+ userErrors {
113
+ field
114
+ message
115
+ }
116
+ }
117
+ }
118
+ ```
119
+ Variables:
120
+ ```json
121
+ {
122
+ "topic": "ORDERS_CREATE",
123
+ "webhookSubscription": {
124
+ "callbackUrl": "https://myapp.example.com/webhooks/orders",
125
+ "format": "JSON",
126
+ "filter": "total_price:>=100.00"
127
+ }
128
+ }
129
+ ```
130
+
131
+ ## Create Webhook with Field Selection
132
+
133
+ ```graphql
134
+ mutation CreateWebhookWithFields($topic: WebhookSubscriptionTopic!, $webhookSubscription: WebhookSubscriptionInput!) {
135
+ webhookSubscriptionCreate(topic: $topic, webhookSubscription: $webhookSubscription) {
136
+ webhookSubscription {
137
+ id
138
+ includeFields
139
+ }
140
+ userErrors {
141
+ field
142
+ message
143
+ }
144
+ }
145
+ }
146
+ ```
147
+ Variables:
148
+ ```json
149
+ {
150
+ "topic": "PRODUCTS_UPDATE",
151
+ "webhookSubscription": {
152
+ "callbackUrl": "https://myapp.example.com/webhooks/products",
153
+ "format": "JSON",
154
+ "includeFields": ["id", "title", "variants"]
155
+ }
156
+ }
157
+ ```
158
+
159
+ ## Create Webhook with Metafields
160
+
161
+ ```graphql
162
+ mutation CreateWebhookWithMetafields($topic: WebhookSubscriptionTopic!, $webhookSubscription: WebhookSubscriptionInput!) {
163
+ webhookSubscriptionCreate(topic: $topic, webhookSubscription: $webhookSubscription) {
164
+ webhookSubscription {
165
+ id
166
+ metafieldNamespaces
167
+ }
168
+ userErrors {
169
+ field
170
+ message
171
+ }
172
+ }
173
+ }
174
+ ```
175
+ Variables:
176
+ ```json
177
+ {
178
+ "topic": "PRODUCTS_UPDATE",
179
+ "webhookSubscription": {
180
+ "callbackUrl": "https://myapp.example.com/webhooks/products",
181
+ "format": "JSON",
182
+ "metafieldNamespaces": ["custom", "my_app"]
183
+ }
184
+ }
185
+ ```
186
+
187
+ ## Create Google Pub/Sub Webhook
188
+
189
+ ```graphql
190
+ mutation CreatePubSubWebhook($topic: WebhookSubscriptionTopic!, $webhookSubscription: WebhookSubscriptionInput!) {
191
+ webhookSubscriptionCreate(topic: $topic, webhookSubscription: $webhookSubscription) {
192
+ webhookSubscription {
193
+ id
194
+ endpoint {
195
+ ... on WebhookPubSubEndpoint {
196
+ pubSubProject
197
+ pubSubTopic
198
+ }
199
+ }
200
+ }
201
+ userErrors {
202
+ field
203
+ message
204
+ }
205
+ }
206
+ }
207
+ ```
208
+ Variables:
209
+ ```json
210
+ {
211
+ "topic": "ORDERS_CREATE",
212
+ "webhookSubscription": {
213
+ "pubSubProject": "my-gcp-project",
214
+ "pubSubTopic": "shopify-orders",
215
+ "format": "JSON"
216
+ }
217
+ }
218
+ ```
219
+
220
+ ## Create AWS EventBridge Webhook
221
+
222
+ ```graphql
223
+ mutation CreateEventBridgeWebhook($topic: WebhookSubscriptionTopic!, $webhookSubscription: WebhookSubscriptionInput!) {
224
+ webhookSubscriptionCreate(topic: $topic, webhookSubscription: $webhookSubscription) {
225
+ webhookSubscription {
226
+ id
227
+ endpoint {
228
+ ... on WebhookEventBridgeEndpoint {
229
+ arn
230
+ }
231
+ }
232
+ }
233
+ userErrors {
234
+ field
235
+ message
236
+ }
237
+ }
238
+ }
239
+ ```
240
+ Variables:
241
+ ```json
242
+ {
243
+ "topic": "ORDERS_CREATE",
244
+ "webhookSubscription": {
245
+ "arn": "arn:aws:events:us-east-1:123456789:event-source/aws.partner/shopify.com/12345/my-source",
246
+ "format": "JSON"
247
+ }
248
+ }
249
+ ```
250
+
251
+ ## Update Webhook
252
+
253
+ ```graphql
254
+ mutation UpdateWebhook($id: ID!, $webhookSubscription: WebhookSubscriptionInput!) {
255
+ webhookSubscriptionUpdate(id: $id, webhookSubscription: $webhookSubscription) {
256
+ webhookSubscription {
257
+ id
258
+ endpoint {
259
+ ... on WebhookHttpEndpoint {
260
+ callbackUrl
261
+ }
262
+ }
263
+ }
264
+ userErrors {
265
+ field
266
+ message
267
+ }
268
+ }
269
+ }
270
+ ```
271
+ Variables:
272
+ ```json
273
+ {
274
+ "id": "gid://shopify/WebhookSubscription/123",
275
+ "webhookSubscription": {
276
+ "callbackUrl": "https://myapp.example.com/webhooks/orders/v2"
277
+ }
278
+ }
279
+ ```
280
+
281
+ ## Delete Webhook
282
+
283
+ > REQUIRES PERMISSION: Deleting a webhook subscription permanently stops event notifications and may break integrations or automated workflows. Always ask the user for explicit confirmation, show the webhook topic and endpoint, and wait for approval before executing this operation.
284
+
285
+ ```graphql
286
+ mutation DeleteWebhook($id: ID!) {
287
+ webhookSubscriptionDelete(id: $id) {
288
+ deletedWebhookSubscriptionId
289
+ userErrors {
290
+ field
291
+ message
292
+ }
293
+ }
294
+ }
295
+ ```
296
+
297
+ ## Common Webhook Topics
298
+
299
+ ### Orders
300
+ | Topic | Event |
301
+ |-------|-------|
302
+ | `ORDERS_CREATE` | New order placed |
303
+ | `ORDERS_UPDATED` | Order modified |
304
+ | `ORDERS_CANCELLED` | Order cancelled |
305
+ | `ORDERS_FULFILLED` | Order fulfilled |
306
+ | `ORDERS_PAID` | Order paid |
307
+
308
+ ### Products
309
+ | Topic | Event |
310
+ |-------|-------|
311
+ | `PRODUCTS_CREATE` | Product created |
312
+ | `PRODUCTS_UPDATE` | Product updated |
313
+ | `PRODUCTS_DELETE` | Product deleted |
314
+
315
+ ### Customers
316
+ | Topic | Event |
317
+ |-------|-------|
318
+ | `CUSTOMERS_CREATE` | Customer created |
319
+ | `CUSTOMERS_UPDATE` | Customer updated |
320
+ | `CUSTOMERS_DELETE` | Customer deleted |
321
+
322
+ ### Inventory
323
+ | Topic | Event |
324
+ |-------|-------|
325
+ | `INVENTORY_LEVELS_UPDATE` | Inventory changed |
326
+
327
+ ### Fulfillment
328
+ | Topic | Event |
329
+ |-------|-------|
330
+ | `FULFILLMENTS_CREATE` | Fulfillment created |
331
+ | `FULFILLMENTS_UPDATE` | Fulfillment updated |
332
+
333
+ ### Refunds
334
+ | Topic | Event |
335
+ |-------|-------|
336
+ | `REFUNDS_CREATE` | Refund processed |
337
+
338
+ ### App
339
+ | Topic | Event |
340
+ |-------|-------|
341
+ | `APP_UNINSTALLED` | App uninstalled |
342
+ | `APP_SUBSCRIPTIONS_UPDATE` | Subscription changed |
343
+
344
+ ## Webhook Formats
345
+
346
+ | Format | Description |
347
+ |--------|-------------|
348
+ | `JSON` | JSON payload |
349
+ | `XML` | XML payload |
350
+
351
+ ## Filter Syntax Examples
352
+
353
+ ```
354
+ # Orders over $100
355
+ total_price:>=100.00
356
+
357
+ # Specific customer
358
+ customer_id:123456
359
+
360
+ # Products with tag
361
+ tags:sale
362
+
363
+ # Combined filters
364
+ total_price:>=50.00 AND financial_status:paid
365
+ ```
366
+
367
+ ## API Scopes Required
368
+
369
+ Different topics require different scopes:
370
+
371
+ | Topic | Required Scope |
372
+ |-------|----------------|
373
+ | `ORDERS_*` | `read_orders` |
374
+ | `PRODUCTS_*` | `read_products` |
375
+ | `CUSTOMERS_*` | `read_customers` |
376
+ | `INVENTORY_*` | `read_inventory` |
377
+
378
+ ## Notes
379
+
380
+ - App-specific webhooks in `shopify.app.toml` are preferred for most apps
381
+ - API-created webhooks are shop-scoped, not app-scoped
382
+ - Webhooks retry failed deliveries with exponential backoff
383
+ - Verify webhook signatures for security
384
+ - Maximum 3 attempts before webhook is marked failed
385
+ - Webhook API version is set at app level, not per subscription
386
+
387
+ ## Dangerous Operations in This Skill
388
+
389
+ The following operations require explicit user permission before execution:
390
+
391
+ | Operation | Impact | Reversible |
392
+ |-----------|--------|------------|
393
+ | `webhookSubscriptionDelete` | Permanently stops event notifications, may break integrations | Yes (can recreate, but data in transit is lost) |
394
+
395
+ Permission Protocol: Before executing `webhookSubscriptionDelete`:
396
+ 1. Show the webhook ID and subscription topic
397
+ 2. Display the endpoint/callback URL or destination
398
+ 3. Explain that event notifications will stop immediately
399
+ 4. Warn about potential impact on integrations and automation
400
+ 5. Wait for explicit user confirmation with "yes", "confirm", or "proceed"
@@ -0,0 +1,18 @@
1
+ import Anthropic from "@anthropic-ai/sdk";
2
+ import { ShopifyClient } from "./shopify";
3
+ export declare class ShopifyAgent {
4
+ private anthropic;
5
+ private shopify;
6
+ private skillContent;
7
+ private model;
8
+ constructor(config: {
9
+ shopify: ShopifyClient;
10
+ skillContent: string;
11
+ model?: string;
12
+ });
13
+ chat(userMessage: string, conversationHistory?: Anthropic.MessageParam[]): Promise<{
14
+ response: string;
15
+ history: Anthropic.MessageParam[];
16
+ }>;
17
+ }
18
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAsB1C,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE;QAClB,OAAO,EAAE,aAAa,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB;IAOK,IAAI,CACR,WAAW,EAAE,MAAM,EACnB,mBAAmB,GAAE,SAAS,CAAC,YAAY,EAAO,GACjD,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,SAAS,CAAC,YAAY,EAAE,CAAA;KAAE,CAAC;CAyFpE"}
package/dist/agent.js ADDED
@@ -0,0 +1,100 @@
1
+ // src/agent.ts
2
+ import Anthropic from "@anthropic-ai/sdk";
3
+ var SHOPIFY_GRAPHQL_TOOL = {
4
+ name: "shopify_graphql",
5
+ description: "Execute a GraphQL query against the Shopify Admin API. Use this to interact with products, orders, customers, inventory, and other Shopify resources.",
6
+ input_schema: {
7
+ type: "object",
8
+ properties: {
9
+ query: {
10
+ type: "string",
11
+ description: "The GraphQL query or mutation to execute"
12
+ },
13
+ variables: {
14
+ type: "object",
15
+ description: "Optional variables for the GraphQL query"
16
+ }
17
+ },
18
+ required: ["query"]
19
+ }
20
+ };
21
+
22
+ class ShopifyAgent {
23
+ anthropic;
24
+ shopify;
25
+ skillContent;
26
+ model;
27
+ constructor(config) {
28
+ this.anthropic = new Anthropic;
29
+ this.shopify = config.shopify;
30
+ this.skillContent = config.skillContent;
31
+ this.model = config.model ?? "claude-sonnet-4-5";
32
+ }
33
+ async chat(userMessage, conversationHistory = []) {
34
+ const systemPrompt = `You are a helpful Shopify assistant that can query and manage a Shopify store using the GraphQL Admin API.
35
+
36
+ ${this.skillContent}
37
+
38
+ When the user asks about products, orders, customers, or any Shopify data, use the shopify_graphql tool to fetch or modify the data. Always explain what you're doing and present results clearly.`;
39
+ const messages = [
40
+ ...conversationHistory,
41
+ { role: "user", content: userMessage }
42
+ ];
43
+ let response = await this.anthropic.messages.create({
44
+ model: this.model,
45
+ max_tokens: 4096,
46
+ system: systemPrompt,
47
+ tools: [SHOPIFY_GRAPHQL_TOOL],
48
+ messages
49
+ });
50
+ const assistantMessages = [];
51
+ while (response.stop_reason === "tool_use") {
52
+ const toolUseBlocks = response.content.filter((block) => block.type === "tool_use");
53
+ assistantMessages.push(...response.content);
54
+ const toolResults = [];
55
+ for (const toolUse of toolUseBlocks) {
56
+ if (toolUse.name === "shopify_graphql") {
57
+ const input = toolUse.input;
58
+ try {
59
+ const result = await this.shopify.graphql(input.query, input.variables);
60
+ toolResults.push({
61
+ type: "tool_result",
62
+ tool_use_id: toolUse.id,
63
+ content: JSON.stringify(result, null, 2)
64
+ });
65
+ } catch (error) {
66
+ toolResults.push({
67
+ type: "tool_result",
68
+ tool_use_id: toolUse.id,
69
+ content: `Error: ${error instanceof Error ? error.message : String(error)}`,
70
+ is_error: true
71
+ });
72
+ }
73
+ }
74
+ }
75
+ messages.push({ role: "assistant", content: assistantMessages.slice() });
76
+ messages.push({ role: "user", content: toolResults });
77
+ assistantMessages.length = 0;
78
+ response = await this.anthropic.messages.create({
79
+ model: this.model,
80
+ max_tokens: 4096,
81
+ system: systemPrompt,
82
+ tools: [SHOPIFY_GRAPHQL_TOOL],
83
+ messages
84
+ });
85
+ }
86
+ const textBlocks = response.content.filter((block) => block.type === "text");
87
+ const finalResponse = textBlocks.map((b) => b.text).join(`
88
+ `);
89
+ const updatedHistory = [
90
+ ...messages,
91
+ { role: "assistant", content: response.content }
92
+ ];
93
+ return { response: finalResponse, history: updatedHistory };
94
+ }
95
+ }
96
+ export {
97
+ ShopifyAgent
98
+ };
99
+
100
+ export { ShopifyAgent };
package/dist/auth.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Shopify OAuth Client Credentials
3
+ * For apps installed on stores you own (server-to-server)
4
+ */
5
+ export interface AccessTokenResponse {
6
+ accessToken: string;
7
+ scope: string;
8
+ expiresIn: number;
9
+ }
10
+ export interface ClientCredentialsConfig {
11
+ storeUrl: string;
12
+ clientId: string;
13
+ clientSecret: string;
14
+ }
15
+ /**
16
+ * Get an access token using the Client Credentials grant.
17
+ * Token expires in 24 hours and must be refreshed with the same request.
18
+ *
19
+ * @see https://shopify.dev/docs/apps/build/authentication-authorization/access-tokens/client-credentials-grant
20
+ */
21
+ export declare function getAccessToken(config: ClientCredentialsConfig): Promise<AccessTokenResponse>;
22
+ /**
23
+ * Create a Shopify client config from environment variables.
24
+ * Supports two authentication methods:
25
+ * 1. Direct access token (SHOPIFY_ACCESS_TOKEN) - uses token directly
26
+ * 2. Client credentials (SHOPIFY_CLIENT_ID + SHOPIFY_CLIENT_SECRET) - fetches token via OAuth
27
+ */
28
+ export declare function createAuthenticatedConfig(): Promise<{
29
+ storeUrl: string;
30
+ accessToken: string;
31
+ scope?: string;
32
+ expiresIn?: number;
33
+ }>;
34
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CAoC9B;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAkCD"}
package/dist/auth.js ADDED
@@ -0,0 +1,58 @@
1
+ // src/auth.ts
2
+ async function getAccessToken(config) {
3
+ const storeUrl = config.storeUrl.replace(/^https?:\/\//, "").replace(/\/$/, "");
4
+ const response = await fetch(`https://${storeUrl}/admin/oauth/access_token`, {
5
+ method: "POST",
6
+ headers: {
7
+ "Content-Type": "application/x-www-form-urlencoded"
8
+ },
9
+ body: new URLSearchParams({
10
+ grant_type: "client_credentials",
11
+ client_id: config.clientId,
12
+ client_secret: config.clientSecret
13
+ })
14
+ });
15
+ if (!response.ok) {
16
+ const text = await response.text();
17
+ throw new Error(`OAuth error (${response.status}): ${text}`);
18
+ }
19
+ const data = await response.json();
20
+ return {
21
+ accessToken: data.access_token,
22
+ scope: data.scope,
23
+ expiresIn: data.expires_in
24
+ };
25
+ }
26
+ async function createAuthenticatedConfig() {
27
+ const storeUrl = process.env.SHOPIFY_STORE_URL;
28
+ const directToken = process.env.SHOPIFY_ACCESS_TOKEN;
29
+ const clientId = process.env.SHOPIFY_CLIENT_ID;
30
+ const clientSecret = process.env.SHOPIFY_CLIENT_SECRET;
31
+ if (!storeUrl) {
32
+ throw new Error("Missing required environment variable: SHOPIFY_STORE_URL");
33
+ }
34
+ if (directToken) {
35
+ return {
36
+ storeUrl,
37
+ accessToken: directToken
38
+ };
39
+ }
40
+ if (clientId && clientSecret) {
41
+ const token = await getAccessToken({ storeUrl, clientId, clientSecret });
42
+ return {
43
+ storeUrl,
44
+ accessToken: token.accessToken,
45
+ scope: token.scope,
46
+ expiresIn: token.expiresIn
47
+ };
48
+ }
49
+ throw new Error(`Missing authentication credentials. Provide either:
50
+ ` + ` - SHOPIFY_ACCESS_TOKEN (direct token), or
51
+ ` + " - SHOPIFY_CLIENT_ID and SHOPIFY_CLIENT_SECRET (OAuth client credentials)");
52
+ }
53
+ export {
54
+ getAccessToken,
55
+ createAuthenticatedConfig
56
+ };
57
+
58
+ export { getAccessToken, createAuthenticatedConfig };
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Clawpify - Shopify Agent SDK
3
+ *
4
+ * Query and manage Shopify stores via GraphQL Admin API with AI agents.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { ShopifyClient } from "clawpify";
9
+ *
10
+ * const client = new ShopifyClient({
11
+ * storeUrl: "my-store.myshopify.com",
12
+ * accessToken: "shpat_xxxxx",
13
+ * });
14
+ *
15
+ * const { data } = await client.graphql(`{
16
+ * products(first: 5) {
17
+ * nodes { id title }
18
+ * }
19
+ * }`);
20
+ * ```
21
+ *
22
+ * @example Using the AI agent (requires @anthropic-ai/sdk)
23
+ * ```ts
24
+ * import { ShopifyClient } from "clawpify";
25
+ * import { ShopifyAgent } from "clawpify/agent";
26
+ * import { loadSkills } from "clawpify/skills";
27
+ *
28
+ * const client = new ShopifyClient({ storeUrl, accessToken });
29
+ * const skills = await loadSkills();
30
+ * const agent = new ShopifyAgent({ shopify: client, skillContent: skills });
31
+ *
32
+ * const result = await agent.chat("List my products");
33
+ * console.log(result.response);
34
+ * ```
35
+ */
36
+ export { ShopifyClient, createShopifyClient } from "./shopify";
37
+ export { createAuthenticatedConfig, getAccessToken, type AccessTokenResponse, type ClientCredentialsConfig, } from "./auth";
38
+ export { ShopifyAgent } from "./agent";
39
+ export { loadSkills } from "./skills";
40
+ export type { ShopifyClientConfig, GraphQLResponse } from "./shopify";
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAGH,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAG/D,OAAO,EACL,yBAAyB,EACzB,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,GAC7B,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ import {
2
+ ShopifyAgent
3
+ } from "./agent.js";
4
+ import {
5
+ ShopifyClient,
6
+ createShopifyClient
7
+ } from "./shopify.js";
8
+ import {
9
+ createAuthenticatedConfig,
10
+ getAccessToken
11
+ } from "./auth.js";
12
+ import {
13
+ loadSkills
14
+ } from "./skills.js";
15
+ export {
16
+ loadSkills,
17
+ getAccessToken,
18
+ createShopifyClient,
19
+ createAuthenticatedConfig,
20
+ ShopifyClient,
21
+ ShopifyAgent
22
+ };
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=mcp-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":""}