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.
- package/ENV_EXAMPLE.md +83 -0
- package/LICENSE +21 -0
- package/README.md +141 -0
- package/SETUP.md +244 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +80 -0
- package/dist/config.js.map +1 -0
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/config.test.js +55 -0
- package/dist/config.test.js.map +1 -0
- package/dist/connections/firebase.d.ts +3 -0
- package/dist/connections/firebase.d.ts.map +1 -0
- package/dist/connections/firebase.js +62 -0
- package/dist/connections/firebase.js.map +1 -0
- package/dist/connections/salesforce.d.ts +3 -0
- package/dist/connections/salesforce.d.ts.map +1 -0
- package/dist/connections/salesforce.js +307 -0
- package/dist/connections/salesforce.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +101 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/payment-context.d.ts +14 -0
- package/dist/resources/payment-context.d.ts.map +1 -0
- package/dist/resources/payment-context.js +111 -0
- package/dist/resources/payment-context.js.map +1 -0
- package/dist/server.d.ts +36 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +14 -0
- package/dist/server.js.map +1 -0
- package/dist/sync-last-purchase.d.ts +3 -0
- package/dist/sync-last-purchase.d.ts.map +1 -0
- package/dist/sync-last-purchase.js +113 -0
- package/dist/sync-last-purchase.js.map +1 -0
- package/dist/tools/definitions.d.ts +3768 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +753 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/handlers/analytics.d.ts +21 -0
- package/dist/tools/handlers/analytics.d.ts.map +1 -0
- package/dist/tools/handlers/analytics.js +398 -0
- package/dist/tools/handlers/analytics.js.map +1 -0
- package/dist/tools/handlers/lemonsqueezy.d.ts +436 -0
- package/dist/tools/handlers/lemonsqueezy.d.ts.map +1 -0
- package/dist/tools/handlers/lemonsqueezy.js +481 -0
- package/dist/tools/handlers/lemonsqueezy.js.map +1 -0
- package/dist/tools/handlers/salesforce.d.ts +13 -0
- package/dist/tools/handlers/salesforce.d.ts.map +1 -0
- package/dist/tools/handlers/salesforce.js +54 -0
- package/dist/tools/handlers/salesforce.js.map +1 -0
- package/dist/tools/handlers/vos.d.ts +26 -0
- package/dist/tools/handlers/vos.d.ts.map +1 -0
- package/dist/tools/handlers/vos.js +207 -0
- package/dist/tools/handlers/vos.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +202 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +24 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +8 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/response.d.ts +14 -0
- package/dist/utils/response.d.ts.map +1 -0
- package/dist/utils/response.js +17 -0
- package/dist/utils/response.js.map +1 -0
- package/dist/utils/retry.d.ts +11 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +36 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/secrets/provider.d.ts +30 -0
- package/dist/utils/secrets/provider.d.ts.map +1 -0
- package/dist/utils/secrets/provider.js +51 -0
- package/dist/utils/secrets/provider.js.map +1 -0
- package/dist/utils/secrets.d.ts +7 -0
- package/dist/utils/secrets.d.ts.map +1 -0
- package/dist/utils/secrets.js +16 -0
- package/dist/utils/secrets.js.map +1 -0
- package/dist/utils/validation.d.ts +580 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +250 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/webhooks/listener.d.ts +17 -0
- package/dist/webhooks/listener.d.ts.map +1 -0
- package/dist/webhooks/listener.js +140 -0
- package/dist/webhooks/listener.js.map +1 -0
- package/dist/webhooks/ngrok.d.ts +8 -0
- package/dist/webhooks/ngrok.d.ts.map +1 -0
- package/dist/webhooks/ngrok.js +50 -0
- package/dist/webhooks/ngrok.js.map +1 -0
- 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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"}
|
package/dist/server.d.ts
ADDED
|
@@ -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 @@
|
|
|
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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"}
|