lemonsqueezy-mcp-server 1.0.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 (97) hide show
  1. package/ENV_EXAMPLE.md +83 -0
  2. package/LICENSE +21 -0
  3. package/README.md +141 -0
  4. package/SETUP.md +244 -0
  5. package/dist/config.d.ts +25 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +80 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/config.test.d.ts +2 -0
  10. package/dist/config.test.d.ts.map +1 -0
  11. package/dist/config.test.js +55 -0
  12. package/dist/config.test.js.map +1 -0
  13. package/dist/connections/firebase.d.ts +3 -0
  14. package/dist/connections/firebase.d.ts.map +1 -0
  15. package/dist/connections/firebase.js +62 -0
  16. package/dist/connections/firebase.js.map +1 -0
  17. package/dist/connections/salesforce.d.ts +3 -0
  18. package/dist/connections/salesforce.d.ts.map +1 -0
  19. package/dist/connections/salesforce.js +307 -0
  20. package/dist/connections/salesforce.js.map +1 -0
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +101 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/resources/payment-context.d.ts +14 -0
  26. package/dist/resources/payment-context.d.ts.map +1 -0
  27. package/dist/resources/payment-context.js +111 -0
  28. package/dist/resources/payment-context.js.map +1 -0
  29. package/dist/server.d.ts +36 -0
  30. package/dist/server.d.ts.map +1 -0
  31. package/dist/server.js +14 -0
  32. package/dist/server.js.map +1 -0
  33. package/dist/sync-last-purchase.d.ts +3 -0
  34. package/dist/sync-last-purchase.d.ts.map +1 -0
  35. package/dist/sync-last-purchase.js +113 -0
  36. package/dist/sync-last-purchase.js.map +1 -0
  37. package/dist/tools/definitions.d.ts +3768 -0
  38. package/dist/tools/definitions.d.ts.map +1 -0
  39. package/dist/tools/definitions.js +753 -0
  40. package/dist/tools/definitions.js.map +1 -0
  41. package/dist/tools/handlers/analytics.d.ts +21 -0
  42. package/dist/tools/handlers/analytics.d.ts.map +1 -0
  43. package/dist/tools/handlers/analytics.js +398 -0
  44. package/dist/tools/handlers/analytics.js.map +1 -0
  45. package/dist/tools/handlers/lemonsqueezy.d.ts +436 -0
  46. package/dist/tools/handlers/lemonsqueezy.d.ts.map +1 -0
  47. package/dist/tools/handlers/lemonsqueezy.js +481 -0
  48. package/dist/tools/handlers/lemonsqueezy.js.map +1 -0
  49. package/dist/tools/handlers/salesforce.d.ts +13 -0
  50. package/dist/tools/handlers/salesforce.d.ts.map +1 -0
  51. package/dist/tools/handlers/salesforce.js +54 -0
  52. package/dist/tools/handlers/salesforce.js.map +1 -0
  53. package/dist/tools/handlers/vos.d.ts +26 -0
  54. package/dist/tools/handlers/vos.d.ts.map +1 -0
  55. package/dist/tools/handlers/vos.js +207 -0
  56. package/dist/tools/handlers/vos.js.map +1 -0
  57. package/dist/tools/index.d.ts +7 -0
  58. package/dist/tools/index.d.ts.map +1 -0
  59. package/dist/tools/index.js +202 -0
  60. package/dist/tools/index.js.map +1 -0
  61. package/dist/types.d.ts +24 -0
  62. package/dist/types.d.ts.map +1 -0
  63. package/dist/types.js +2 -0
  64. package/dist/types.js.map +1 -0
  65. package/dist/utils/logger.d.ts +3 -0
  66. package/dist/utils/logger.d.ts.map +1 -0
  67. package/dist/utils/logger.js +8 -0
  68. package/dist/utils/logger.js.map +1 -0
  69. package/dist/utils/response.d.ts +14 -0
  70. package/dist/utils/response.d.ts.map +1 -0
  71. package/dist/utils/response.js +17 -0
  72. package/dist/utils/response.js.map +1 -0
  73. package/dist/utils/retry.d.ts +11 -0
  74. package/dist/utils/retry.d.ts.map +1 -0
  75. package/dist/utils/retry.js +36 -0
  76. package/dist/utils/retry.js.map +1 -0
  77. package/dist/utils/secrets/provider.d.ts +30 -0
  78. package/dist/utils/secrets/provider.d.ts.map +1 -0
  79. package/dist/utils/secrets/provider.js +51 -0
  80. package/dist/utils/secrets/provider.js.map +1 -0
  81. package/dist/utils/secrets.d.ts +7 -0
  82. package/dist/utils/secrets.d.ts.map +1 -0
  83. package/dist/utils/secrets.js +16 -0
  84. package/dist/utils/secrets.js.map +1 -0
  85. package/dist/utils/validation.d.ts +580 -0
  86. package/dist/utils/validation.d.ts.map +1 -0
  87. package/dist/utils/validation.js +250 -0
  88. package/dist/utils/validation.js.map +1 -0
  89. package/dist/webhooks/listener.d.ts +17 -0
  90. package/dist/webhooks/listener.d.ts.map +1 -0
  91. package/dist/webhooks/listener.js +140 -0
  92. package/dist/webhooks/listener.js.map +1 -0
  93. package/dist/webhooks/ngrok.d.ts +8 -0
  94. package/dist/webhooks/ngrok.d.ts.map +1 -0
  95. package/dist/webhooks/ngrok.js +50 -0
  96. package/dist/webhooks/ngrok.js.map +1 -0
  97. package/package.json +68 -0
@@ -0,0 +1,111 @@
1
+ import { watch } from "fs";
2
+ import { readFile } from "fs/promises";
3
+ import { listOrders } from "@lemonsqueezy/lemonsqueezy.js";
4
+ import { config } from "../config.js";
5
+ import { logger } from "../utils/logger.js";
6
+ let paymentContext = [];
7
+ const MAX_CONTEXT_EVENTS = 10;
8
+ export function addPaymentEvent(event) {
9
+ paymentContext.unshift(event);
10
+ if (paymentContext.length > MAX_CONTEXT_EVENTS) {
11
+ paymentContext = paymentContext.slice(0, MAX_CONTEXT_EVENTS);
12
+ }
13
+ }
14
+ export function setupPaymentContextWatcher() {
15
+ if (!config.enableResources || !config.webhookLogPath) {
16
+ return;
17
+ }
18
+ const logPath = config.webhookLogPath;
19
+ logger.info({ logPath }, "Watching webhook log");
20
+ try {
21
+ watch(logPath, { persistent: true }, async (eventType) => {
22
+ if (eventType === "change") {
23
+ try {
24
+ const content = await readFile(logPath, "utf-8");
25
+ const lines = content.split("\n").filter((l) => l.trim());
26
+ const lastLine = lines[lines.length - 1];
27
+ // Parse webhook event (adjust based on your log format)
28
+ if (lastLine.includes("order") ||
29
+ lastLine.includes("subscription") ||
30
+ lastLine.includes("payment")) {
31
+ const event = {
32
+ timestamp: new Date().toISOString(),
33
+ type: "webhook",
34
+ message: lastLine,
35
+ };
36
+ // Try to extract order info from log
37
+ const orderMatch = lastLine.match(/order[_\s#]?(\d+)/i);
38
+ if (orderMatch)
39
+ event.orderId = parseInt(orderMatch[1]);
40
+ const emailMatch = lastLine.match(/([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/);
41
+ if (emailMatch)
42
+ event.customerEmail = emailMatch[1];
43
+ const statusMatch = lastLine.match(/(paid|refunded|failed|cancelled|active|expired)/i);
44
+ if (statusMatch)
45
+ event.status = statusMatch[1].toLowerCase();
46
+ paymentContext.unshift(event);
47
+ if (paymentContext.length > MAX_CONTEXT_EVENTS) {
48
+ paymentContext = paymentContext.slice(0, MAX_CONTEXT_EVENTS);
49
+ }
50
+ }
51
+ }
52
+ catch (err) {
53
+ // Silently handle read errors
54
+ }
55
+ }
56
+ });
57
+ }
58
+ catch (err) {
59
+ logger.error({ error: err, logPath }, "Error watching log file");
60
+ }
61
+ }
62
+ export function setupFailedPaymentPolling() {
63
+ if (!config.enableResources || !config.pollFailedPayments) {
64
+ return;
65
+ }
66
+ const pollInterval = config.pollIntervalMinutes * 60 * 1000;
67
+ setInterval(async () => {
68
+ try {
69
+ const { data, error } = await listOrders({ page: { number: 1, size: 5 } });
70
+ if (error || !data?.data)
71
+ return;
72
+ const failedOrders = data.data.filter((order) => {
73
+ const status = order.attributes?.status;
74
+ return status === "refunded" || status === "failed" || status === "cancelled";
75
+ });
76
+ for (const order of failedOrders) {
77
+ const existing = paymentContext.find((e) => e.orderId === parseInt(order.id));
78
+ if (!existing) {
79
+ paymentContext.unshift({
80
+ timestamp: order.attributes?.created_at || new Date().toISOString(),
81
+ type: "failed_payment",
82
+ orderId: parseInt(order.id),
83
+ customerEmail: order.attributes?.user_email,
84
+ status: order.attributes?.status,
85
+ amount: order.attributes?.total_formatted,
86
+ message: `Failed payment: Order #${order.id} - ${order.attributes?.status} - ${order.attributes?.total_formatted}`,
87
+ });
88
+ }
89
+ }
90
+ if (paymentContext.length > MAX_CONTEXT_EVENTS) {
91
+ paymentContext = paymentContext.slice(0, MAX_CONTEXT_EVENTS);
92
+ }
93
+ }
94
+ catch (err) {
95
+ // Silently handle polling errors
96
+ }
97
+ }, pollInterval);
98
+ logger.info({ intervalMinutes: config.pollIntervalMinutes }, "Polling failed payments");
99
+ }
100
+ export function getPaymentContextResource() {
101
+ return {
102
+ lastUpdated: new Date().toISOString(),
103
+ totalEvents: paymentContext.length,
104
+ events: paymentContext,
105
+ summary: {
106
+ failedPayments: paymentContext.filter((e) => e.status === "failed" || e.status === "refunded").length,
107
+ recentActivity: paymentContext.slice(0, 5).map((e) => e.message),
108
+ },
109
+ };
110
+ }
111
+ //# sourceMappingURL=payment-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment-context.js","sourceRoot":"","sources":["../../src/resources/payment-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ export declare function createServer(): Server<{
3
+ method: string;
4
+ params?: {
5
+ [x: string]: unknown;
6
+ _meta?: {
7
+ [x: string]: unknown;
8
+ progressToken?: string | number | undefined;
9
+ "io.modelcontextprotocol/related-task"?: {
10
+ taskId: string;
11
+ } | undefined;
12
+ } | undefined;
13
+ } | undefined;
14
+ }, {
15
+ method: string;
16
+ params?: {
17
+ [x: string]: unknown;
18
+ _meta?: {
19
+ [x: string]: unknown;
20
+ progressToken?: string | number | undefined;
21
+ "io.modelcontextprotocol/related-task"?: {
22
+ taskId: string;
23
+ } | undefined;
24
+ } | undefined;
25
+ } | undefined;
26
+ }, {
27
+ [x: string]: unknown;
28
+ _meta?: {
29
+ [x: string]: unknown;
30
+ progressToken?: string | number | undefined;
31
+ "io.modelcontextprotocol/related-task"?: {
32
+ taskId: string;
33
+ } | undefined;
34
+ } | undefined;
35
+ }>;
36
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGnE,wBAAgB,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAa3B"}
package/dist/server.js ADDED
@@ -0,0 +1,14 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import { config } from "./config.js";
3
+ export function createServer() {
4
+ return new Server({
5
+ name: "lemonsqueezy-antigravity-bridge",
6
+ version: "1.0.0",
7
+ }, {
8
+ capabilities: {
9
+ tools: {},
10
+ resources: config.enableResources ? {} : undefined,
11
+ },
12
+ });
13
+ }
14
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,MAAM,CACf;QACE,IAAI,EAAE,iCAAiC;QACvC,OAAO,EAAE,OAAO;KACjB,EACD;QACE,YAAY,EAAE;YACZ,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;SACnD;KACF,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=sync-last-purchase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-last-purchase.d.ts","sourceRoot":"","sources":["../sync-last-purchase.ts"],"names":[],"mappings":""}
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+ import { lemonSqueezySetup, listOrders } from "@lemonsqueezy/lemonsqueezy.js";
3
+ import jsforce from "jsforce";
4
+ import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
5
+ import jwt from "jsonwebtoken";
6
+ import * as dotenv from "dotenv";
7
+ dotenv.config();
8
+ const apiKey = process.env.LEMONSQUEEZY_API_KEY || process.env.LEMONSQUEEZY_TEST_API_KEY;
9
+ if (!apiKey)
10
+ throw new Error("API key required");
11
+ lemonSqueezySetup({ apiKey });
12
+ async function getSalesforceConnection() {
13
+ const secretName = process.env.AWS_SALESFORCE_SECRET_NAME;
14
+ if (secretName) {
15
+ const client = new SecretsManagerClient({
16
+ region: process.env.AWS_REGION || "us-east-1"
17
+ });
18
+ const response = await client.send(new GetSecretValueCommand({ SecretId: secretName }));
19
+ const secret = JSON.parse(response.SecretString);
20
+ // Check for JWT authentication
21
+ if (secret.client_id && secret.username && secret.private_key) {
22
+ const loginUrl = secret.loginUrl || "https://login.salesforce.com";
23
+ // Format private key - handle multiple formats
24
+ let privateKey = secret.private_key
25
+ .replace(/\\n/g, "\n")
26
+ .replace(/\\r/g, "")
27
+ .trim();
28
+ // If key is single line (space-separated), convert to proper PEM format
29
+ if (!privateKey.includes("\n")) {
30
+ const match = privateKey.match(/^(-----BEGIN PRIVATE KEY-----) (.+) (-----END PRIVATE KEY-----)$/);
31
+ if (match) {
32
+ const [, header, body, footer] = match;
33
+ const lines = [];
34
+ for (let i = 0; i < body.length; i += 64) {
35
+ lines.push(body.substring(i, i + 64));
36
+ }
37
+ privateKey = `${header}\n${lines.join("\n")}\n${footer}`;
38
+ }
39
+ }
40
+ // Create JWT assertion
41
+ const now = Math.floor(Date.now() / 1000);
42
+ const assertion = jwt.sign({
43
+ iss: secret.client_id,
44
+ sub: secret.username,
45
+ aud: loginUrl,
46
+ exp: now + 300,
47
+ iat: now,
48
+ }, privateKey, { algorithm: "RS256" });
49
+ // Exchange JWT for access token
50
+ const tokenUrl = `${loginUrl}/services/oauth2/token`;
51
+ const tokenResponse = await fetch(tokenUrl, {
52
+ method: "POST",
53
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
54
+ body: new URLSearchParams({
55
+ grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
56
+ assertion: assertion,
57
+ }),
58
+ });
59
+ if (!tokenResponse.ok) {
60
+ throw new Error(`JWT auth failed: ${tokenResponse.status} ${await tokenResponse.text()}`);
61
+ }
62
+ const tokenData = await tokenResponse.json();
63
+ return new jsforce.Connection({
64
+ accessToken: tokenData.access_token,
65
+ instanceUrl: tokenData.instance_url,
66
+ });
67
+ }
68
+ // Fallback to username/password
69
+ const conn = new jsforce.Connection({
70
+ loginUrl: secret.loginUrl || "https://login.salesforce.com"
71
+ });
72
+ await conn.login(secret.username, secret.password + secret.securityToken);
73
+ return conn;
74
+ }
75
+ // Environment variables fallback
76
+ const conn = new jsforce.Connection({
77
+ loginUrl: process.env.SALESFORCE_LOGIN_URL || "https://login.salesforce.com"
78
+ });
79
+ await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD + process.env.SALESFORCE_TOKEN);
80
+ return conn;
81
+ }
82
+ async function syncLastPurchase() {
83
+ const { data, error } = await listOrders({ page: { number: 1, size: 1 } });
84
+ if (error || !data?.data?.[0])
85
+ throw new Error("No orders found");
86
+ const order = data.data[0];
87
+ const attrs = order.attributes;
88
+ const email = attrs?.user_email;
89
+ const name = attrs?.user_name;
90
+ if (!email || !name)
91
+ throw new Error("Missing customer details");
92
+ const conn = await getSalesforceConnection();
93
+ // Check existing lead
94
+ const existing = await conn.query(`SELECT Id FROM Lead WHERE Email = '${email.replace(/'/g, "''")}' LIMIT 1`);
95
+ if (existing.records?.length) {
96
+ console.log(`Lead exists: ${existing.records[0].Id}`);
97
+ return;
98
+ }
99
+ // Create lead with company and title
100
+ const result = await conn.sobject("Lead").create({
101
+ LastName: name,
102
+ Email: email,
103
+ Company: name,
104
+ Title: "Customer",
105
+ LeadSource: "AI Agent",
106
+ AnnualRevenue: attrs?.total ? attrs.total / 100 : undefined
107
+ });
108
+ if (!result.success)
109
+ throw new Error("Failed to create lead");
110
+ console.log(`Created lead: ${result.id}`);
111
+ }
112
+ syncLastPurchase().catch(console.error);
113
+ //# sourceMappingURL=sync-last-purchase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-last-purchase.js","sourceRoot":"","sources":["../sync-last-purchase.ts"],"names":[],"mappings":"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"}