@yawlabs/lemonsqueezy-mcp 0.14.2 → 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/CHANGELOG.md +44 -1
- package/LICENSE +21 -21
- package/README.md +429 -410
- package/bin/lemonsqueezy-mcp.mjs +667 -665
- package/dist/index.js +156 -98
- package/package.json +77 -77
package/dist/index.js
CHANGED
|
@@ -31561,6 +31561,56 @@ function logEvent(entry) {
|
|
|
31561
31561
|
}
|
|
31562
31562
|
}
|
|
31563
31563
|
|
|
31564
|
+
// src/redact.ts
|
|
31565
|
+
var SECRET_KEY_RE = /^(secret|password|token|api[_-]?key|bearer|authorization|signing[_-]?secret|private[_-]?key|pin|ssn|social[_-]?security[_-]?number|credit[_-]?card|card[_-]?number|cvv|cvc)$/i;
|
|
31566
|
+
var JWT_VALUE_RE = /^eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}$/;
|
|
31567
|
+
var LICENSE_KEY_RE = /^license[_-]?key$/i;
|
|
31568
|
+
var MIN_LICENSE_KEY_MASK_LENGTH = 16;
|
|
31569
|
+
var REDACTED = "[REDACTED]";
|
|
31570
|
+
var CIRCULAR = "[CIRCULAR]";
|
|
31571
|
+
function maskLicenseKey(value) {
|
|
31572
|
+
if (typeof value !== "string" || value.length < MIN_LICENSE_KEY_MASK_LENGTH) return REDACTED;
|
|
31573
|
+
return `[REDACTED:last4=${value.slice(-4)}]`;
|
|
31574
|
+
}
|
|
31575
|
+
var MAX_DEPTH = 32;
|
|
31576
|
+
function isPlainObject3(value) {
|
|
31577
|
+
if (value === null || typeof value !== "object") return false;
|
|
31578
|
+
const proto = Object.getPrototypeOf(value);
|
|
31579
|
+
return proto === Object.prototype || proto === null;
|
|
31580
|
+
}
|
|
31581
|
+
function looksLikeBearerToken(value) {
|
|
31582
|
+
if (typeof value !== "string") return false;
|
|
31583
|
+
if (value.length < 20) return false;
|
|
31584
|
+
return JWT_VALUE_RE.test(value);
|
|
31585
|
+
}
|
|
31586
|
+
function redactInner(value, ancestors, memo, depth) {
|
|
31587
|
+
if (depth > MAX_DEPTH) return CIRCULAR;
|
|
31588
|
+
if (typeof value === "string" && looksLikeBearerToken(value)) return REDACTED;
|
|
31589
|
+
if (value === null || typeof value !== "object") return value;
|
|
31590
|
+
const isArray = Array.isArray(value);
|
|
31591
|
+
if (!isArray && !isPlainObject3(value)) return value;
|
|
31592
|
+
if (ancestors.has(value)) return CIRCULAR;
|
|
31593
|
+
const cached3 = memo.get(value);
|
|
31594
|
+
if (cached3 !== void 0 && cached3.depth <= depth) return cached3.result;
|
|
31595
|
+
ancestors.add(value);
|
|
31596
|
+
let result;
|
|
31597
|
+
if (isArray) {
|
|
31598
|
+
result = value.map((item) => redactInner(item, ancestors, memo, depth + 1));
|
|
31599
|
+
} else {
|
|
31600
|
+
const out = {};
|
|
31601
|
+
for (const [key, val] of Object.entries(value)) {
|
|
31602
|
+
out[key] = SECRET_KEY_RE.test(key) ? REDACTED : LICENSE_KEY_RE.test(key) ? maskLicenseKey(val) : redactInner(val, ancestors, memo, depth + 1);
|
|
31603
|
+
}
|
|
31604
|
+
result = out;
|
|
31605
|
+
}
|
|
31606
|
+
ancestors.delete(value);
|
|
31607
|
+
memo.set(value, { depth, result });
|
|
31608
|
+
return result;
|
|
31609
|
+
}
|
|
31610
|
+
function redactSecrets(input) {
|
|
31611
|
+
return redactInner(input, /* @__PURE__ */ new WeakSet(), /* @__PURE__ */ new WeakMap(), 0);
|
|
31612
|
+
}
|
|
31613
|
+
|
|
31564
31614
|
// src/retry.ts
|
|
31565
31615
|
var REQUEST_TIMEOUT_MS = 3e4;
|
|
31566
31616
|
var DEFAULT_RETRY_WAIT_MS = 1e3;
|
|
@@ -31778,6 +31828,10 @@ function invalidateApiKeyCache() {
|
|
|
31778
31828
|
// src/api.ts
|
|
31779
31829
|
var BASE_URL = "https://api.lemonsqueezy.com/v1";
|
|
31780
31830
|
var lsIdSchema = external_exports.string().max(1e4).regex(/^[1-9]\d*$/, "ID must be a positive integer string (e.g. '12345')");
|
|
31831
|
+
var lsUuidSchema = external_exports.string().max(1e4).regex(
|
|
31832
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
|
|
31833
|
+
"ID must be a UUID (e.g. '5e8b546c-c561-4a2c-a586-40c18bb2a195')"
|
|
31834
|
+
);
|
|
31781
31835
|
function encodePath(segment) {
|
|
31782
31836
|
return encodeURIComponent(String(segment));
|
|
31783
31837
|
}
|
|
@@ -31809,30 +31863,17 @@ function decorateError(error51, requestId) {
|
|
|
31809
31863
|
return requestId ? `${error51} (request_id: ${requestId})` : error51;
|
|
31810
31864
|
}
|
|
31811
31865
|
function extractErrorMessage(parsed) {
|
|
31812
|
-
|
|
31813
|
-
|
|
31866
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
31867
|
+
const envelope = parsed;
|
|
31868
|
+
const first = Array.isArray(envelope.errors) ? envelope.errors[0] : void 0;
|
|
31869
|
+
const str = (v) => typeof v === "string" ? v : void 0;
|
|
31870
|
+
return str(first?.detail) ?? str(first?.title) ?? str(envelope.error) ?? null;
|
|
31814
31871
|
}
|
|
31815
31872
|
async function handleErrorResponse(res, route, latency_ms, requestId) {
|
|
31816
31873
|
const errorBody = await res.text();
|
|
31874
|
+
let parsed;
|
|
31817
31875
|
try {
|
|
31818
|
-
|
|
31819
|
-
const detail = extractErrorMessage(parsed) ?? errorBody;
|
|
31820
|
-
logEvent({
|
|
31821
|
-
event: "http_call",
|
|
31822
|
-
method: route.method,
|
|
31823
|
-
path: route.path,
|
|
31824
|
-
status: res.status,
|
|
31825
|
-
latency_ms,
|
|
31826
|
-
request_id: requestId,
|
|
31827
|
-
error: detail
|
|
31828
|
-
});
|
|
31829
|
-
return {
|
|
31830
|
-
ok: false,
|
|
31831
|
-
status: res.status,
|
|
31832
|
-
data: parsed,
|
|
31833
|
-
error: decorateError(detail, requestId),
|
|
31834
|
-
requestId
|
|
31835
|
-
};
|
|
31876
|
+
parsed = JSON.parse(errorBody);
|
|
31836
31877
|
} catch {
|
|
31837
31878
|
logEvent({
|
|
31838
31879
|
event: "http_call",
|
|
@@ -31850,6 +31891,23 @@ async function handleErrorResponse(res, route, latency_ms, requestId) {
|
|
|
31850
31891
|
requestId
|
|
31851
31892
|
};
|
|
31852
31893
|
}
|
|
31894
|
+
const detail = extractErrorMessage(parsed) ?? JSON.stringify(redactSecrets(parsed));
|
|
31895
|
+
logEvent({
|
|
31896
|
+
event: "http_call",
|
|
31897
|
+
method: route.method,
|
|
31898
|
+
path: route.path,
|
|
31899
|
+
status: res.status,
|
|
31900
|
+
latency_ms,
|
|
31901
|
+
request_id: requestId,
|
|
31902
|
+
error: detail
|
|
31903
|
+
});
|
|
31904
|
+
return {
|
|
31905
|
+
ok: false,
|
|
31906
|
+
status: res.status,
|
|
31907
|
+
data: parsed,
|
|
31908
|
+
error: decorateError(detail, requestId),
|
|
31909
|
+
requestId
|
|
31910
|
+
};
|
|
31853
31911
|
}
|
|
31854
31912
|
async function readJsonBody(res) {
|
|
31855
31913
|
const bodyText = await res.text();
|
|
@@ -32080,7 +32138,9 @@ var checkoutTools = [
|
|
|
32080
32138
|
openWorldHint: true
|
|
32081
32139
|
},
|
|
32082
32140
|
inputSchema: external_exports.object({
|
|
32083
|
-
checkoutId:
|
|
32141
|
+
checkoutId: lsUuidSchema.describe(
|
|
32142
|
+
"The checkout ID (a UUID, as returned by ls_list_checkouts / ls_create_checkout)"
|
|
32143
|
+
),
|
|
32084
32144
|
include: external_exports.string().max(1e4).optional().describe("Comma-separated related resources to include (e.g. 'store,variant')")
|
|
32085
32145
|
}),
|
|
32086
32146
|
handler: getHandler("/checkouts", "checkoutId")
|
|
@@ -32248,7 +32308,12 @@ var customerTools = [
|
|
|
32248
32308
|
annotations: {
|
|
32249
32309
|
title: "Update customer",
|
|
32250
32310
|
readOnlyHint: false,
|
|
32251
|
-
|
|
32311
|
+
// Static true: MCP defines false as "only additive updates", and every
|
|
32312
|
+
// field here overwrites the existing value (status can archive). The
|
|
32313
|
+
// predicate below still decides per call whether the server-side
|
|
32314
|
+
// destructive limiter and audit log engage (isDestructiveCall in
|
|
32315
|
+
// guardrails.ts never reads this hint when a predicate exists).
|
|
32316
|
+
destructiveHint: true,
|
|
32252
32317
|
idempotentHint: true,
|
|
32253
32318
|
openWorldHint: true
|
|
32254
32319
|
},
|
|
@@ -32615,25 +32680,31 @@ var licenseKeyTools = [
|
|
|
32615
32680
|
{
|
|
32616
32681
|
name: "ls_update_license_key",
|
|
32617
32682
|
authorityClass: "key",
|
|
32618
|
-
description: "Update a license key's activation limit, expiry date, or disabled status. Setting `disabled: true`
|
|
32683
|
+
description: "Update a license key's activation limit, expiry date, or disabled status. Setting `disabled: true`, changing `activationLimit`, or changing `expiresAt` can revoke customer access and is treated as destructive (rate-limited and audited); `disabled: false` alone is not.",
|
|
32619
32684
|
annotations: {
|
|
32620
32685
|
title: "Update license key",
|
|
32621
32686
|
readOnlyHint: false,
|
|
32622
|
-
|
|
32687
|
+
// Static true: MCP defines false as "only additive updates", and
|
|
32688
|
+
// several inputs here can revoke access. The predicate below still
|
|
32689
|
+
// decides per call whether the server-side destructive limiter and
|
|
32690
|
+
// audit log engage (isDestructiveCall in guardrails.ts never reads this
|
|
32691
|
+
// hint when a predicate exists).
|
|
32692
|
+
destructiveHint: true,
|
|
32623
32693
|
idempotentHint: true,
|
|
32624
32694
|
openWorldHint: true
|
|
32625
32695
|
},
|
|
32626
32696
|
// Disabling a license key revokes a customer's access outright. Changing
|
|
32627
|
-
// the activation limit can also
|
|
32628
|
-
//
|
|
32629
|
-
//
|
|
32630
|
-
//
|
|
32631
|
-
// `activationLimit` change as destructive
|
|
32632
|
-
//
|
|
32633
|
-
|
|
32697
|
+
// the activation limit or the expiry can also narrow it -- a lower cap on
|
|
32698
|
+
// activations, an earlier end date. We can't tell from the input alone
|
|
32699
|
+
// whether a given change narrows or widens access (a number or a date can
|
|
32700
|
+
// go either way against the current value, which we don't fetch), so
|
|
32701
|
+
// treat ANY `activationLimit` or `expiresAt` change as destructive
|
|
32702
|
+
// alongside `disabled: true`, including null. Only `disabled: false`
|
|
32703
|
+
// (re-enabling) stays on the regular path.
|
|
32704
|
+
isDestructive: (input) => input.disabled === true || input.activationLimit !== void 0 || input.expiresAt !== void 0,
|
|
32634
32705
|
inputSchema: external_exports.object({
|
|
32635
32706
|
licenseKeyId: lsIdSchema.describe("The license key ID to update"),
|
|
32636
|
-
activationLimit: external_exports.number().int().min(0).optional().describe("Maximum number of activations allowed
|
|
32707
|
+
activationLimit: external_exports.number().int().min(0).nullable().optional().describe("Maximum number of activations allowed. Pass null for unlimited."),
|
|
32637
32708
|
disabled: external_exports.boolean().optional().describe("Set to true to disable this license key"),
|
|
32638
32709
|
expiresAt: external_exports.string().max(1e4).nullable().optional().describe("Expiry date (ISO 8601 format). Set to null to remove expiry.")
|
|
32639
32710
|
}),
|
|
@@ -32706,11 +32777,11 @@ var licenseTools = [
|
|
|
32706
32777
|
{
|
|
32707
32778
|
name: "ls_deactivate_license",
|
|
32708
32779
|
authorityClass: "key",
|
|
32709
|
-
description: "Deactivate a license key instance. Does not require an API key \u2014 uses the license key itself for auth.",
|
|
32780
|
+
description: "Deactivate a license key instance, revoking that instance's access. Destructive: rate-limited and audited, with the license key masked in the audit entry. Does not require an API key \u2014 uses the license key itself for auth.",
|
|
32710
32781
|
annotations: {
|
|
32711
32782
|
title: "Deactivate license",
|
|
32712
32783
|
readOnlyHint: false,
|
|
32713
|
-
destructiveHint:
|
|
32784
|
+
destructiveHint: true,
|
|
32714
32785
|
idempotentHint: true,
|
|
32715
32786
|
openWorldHint: true
|
|
32716
32787
|
},
|
|
@@ -33569,25 +33640,43 @@ var subscriptionTools = [
|
|
|
33569
33640
|
{
|
|
33570
33641
|
name: "ls_update_subscription",
|
|
33571
33642
|
authorityClass: "recurring",
|
|
33572
|
-
description: "Update a subscription. Can change the variant (plan switch), pause/unpause, set billing anchor, or update invoice details. Pausing (`pause: 'void'` or `'free'`)
|
|
33643
|
+
description: "Update a subscription. Can change the variant (plan switch), pause/unpause, set billing anchor, or update invoice details. Pausing (`pause: 'void'` or `'free'`), switching plan (`variantId`), changing the billing anchor (`billingAnchor`), invoicing immediately (`invoiceImmediately: true`), or changing the trial end (`trialEndsAt`) changes what the customer pays or when, and is treated as destructive (rate-limited and audited); resuming (`pause: 'resume'`), un-cancelling (`cancelled: false`), `invoiceImmediately: false` and `disableProrations` are not. Use ls_cancel_subscription for cancellation.",
|
|
33573
33644
|
annotations: {
|
|
33574
33645
|
title: "Update subscription",
|
|
33575
33646
|
readOnlyHint: false,
|
|
33576
|
-
|
|
33647
|
+
// Static true: MCP defines false as "only additive updates", and
|
|
33648
|
+
// several inputs here pause, re-plan or re-bill the customer. The
|
|
33649
|
+
// predicate below still decides per call whether the server-side
|
|
33650
|
+
// destructive limiter and audit log engage (isDestructiveCall in
|
|
33651
|
+
// guardrails.ts never reads this hint when a predicate exists).
|
|
33652
|
+
destructiveHint: true,
|
|
33577
33653
|
idempotentHint: true,
|
|
33578
33654
|
openWorldHint: true
|
|
33579
33655
|
},
|
|
33580
|
-
//
|
|
33581
|
-
//
|
|
33582
|
-
//
|
|
33583
|
-
//
|
|
33584
|
-
// -
|
|
33585
|
-
//
|
|
33586
|
-
//
|
|
33587
|
-
// -
|
|
33588
|
-
//
|
|
33589
|
-
//
|
|
33590
|
-
|
|
33656
|
+
// The calls that change what the customer pays, or when, are destructive
|
|
33657
|
+
// so they engage the rate limiter and audit log:
|
|
33658
|
+
// - pause "void" / "free" pauses the subscription
|
|
33659
|
+
// - variantId plan switch
|
|
33660
|
+
// - billingAnchor per LemonSqueezy's update-subscription docs,
|
|
33661
|
+
// a new anchor issues a paid, prorated trial
|
|
33662
|
+
// that is charged when it ends
|
|
33663
|
+
// - invoiceImmediately: true per the same docs, the update is charged
|
|
33664
|
+
// now: a prorated invoice is generated and
|
|
33665
|
+
// payment attempted
|
|
33666
|
+
// - trialEndsAt (any value) ending or shortening a trial brings the
|
|
33667
|
+
// first charge forward; extending it does
|
|
33668
|
+
// not, but telling which needs a fetch, so
|
|
33669
|
+
// any change (null included) counts
|
|
33670
|
+
// Intentional exclusions:
|
|
33671
|
+
// - pause === "resume" un-pause
|
|
33672
|
+
// - cancelled === false un-cancel before expiry
|
|
33673
|
+
// These two are a consistent pair: each reverses a destructive action
|
|
33674
|
+
// and returns the customer to billing they had already agreed to, so
|
|
33675
|
+
// they are treated alike.
|
|
33676
|
+
// - invoiceImmediately: false the default proration behaviour
|
|
33677
|
+
// - disableProrations toggle on plan-change behavior; the plan
|
|
33678
|
+
// change itself (variantId) already counts
|
|
33679
|
+
isDestructive: (input) => typeof input.pause === "string" && input.pause !== "resume" || typeof input.variantId === "string" || input.billingAnchor !== void 0 || input.invoiceImmediately === true || input.trialEndsAt !== void 0,
|
|
33591
33680
|
inputSchema: external_exports.object({
|
|
33592
33681
|
subscriptionId: lsIdSchema.describe("The subscription ID to update"),
|
|
33593
33682
|
variantId: lsIdSchema.optional().describe("New variant ID for plan switching"),
|
|
@@ -33685,7 +33774,12 @@ var usageRecordTools = [
|
|
|
33685
33774
|
},
|
|
33686
33775
|
{
|
|
33687
33776
|
name: "ls_create_usage_record",
|
|
33688
|
-
|
|
33777
|
+
// `recurring`, not `mutate`: a usage record changes the metered bill on a
|
|
33778
|
+
// subscription item, the same authority as ls_update_subscription_item's
|
|
33779
|
+
// quantity change. So LEMONSQUEEZY_DISABLE_CLASSES=recurring blocks it,
|
|
33780
|
+
// and a `recurring:N` budget in LEMONSQUEEZY_RATE_LIMIT_PER_CLASS counts
|
|
33781
|
+
// usage reports alongside subscription changes.
|
|
33782
|
+
authorityClass: "recurring",
|
|
33689
33783
|
description: "Report usage for a metered subscription item. Use 'increment' action to add to the current usage, or 'set' to replace it.",
|
|
33690
33784
|
annotations: {
|
|
33691
33785
|
title: "Create usage record",
|
|
@@ -33865,14 +33959,22 @@ var webhookTools = [
|
|
|
33865
33959
|
annotations: {
|
|
33866
33960
|
title: "Update webhook",
|
|
33867
33961
|
readOnlyHint: false,
|
|
33868
|
-
|
|
33962
|
+
// Static true: MCP defines false as "only additive updates", and every
|
|
33963
|
+
// field here overwrites the existing value. The predicate below still
|
|
33964
|
+
// decides per call whether the server-side destructive limiter and
|
|
33965
|
+
// audit log engage (isDestructiveCall in guardrails.ts never reads this
|
|
33966
|
+
// hint when a predicate exists).
|
|
33967
|
+
destructiveHint: true,
|
|
33869
33968
|
idempotentHint: true,
|
|
33870
33969
|
openWorldHint: true
|
|
33871
33970
|
},
|
|
33872
|
-
// Rotating the signing secret
|
|
33873
|
-
//
|
|
33874
|
-
//
|
|
33875
|
-
//
|
|
33971
|
+
// Rotating the signing secret breaks signature verification on every
|
|
33972
|
+
// receiver until they redeploy with the new value, and the agent cannot
|
|
33973
|
+
// undo it: the secret is returned only once (see ls_create_webhook), so
|
|
33974
|
+
// the old value cannot be read back and restored. URL and events
|
|
33975
|
+
// changes can be undone -- ls_get_webhook returns the current URL and
|
|
33976
|
+
// events, and a PATCH puts them back -- so they stay on the regular path.
|
|
33977
|
+
// The `secret` input reaches the audit log redacted by key name.
|
|
33876
33978
|
isDestructive: (input) => input.secret !== void 0,
|
|
33877
33979
|
inputSchema: external_exports.object({
|
|
33878
33980
|
webhookId: lsIdSchema.describe("The webhook ID to update"),
|
|
@@ -33941,50 +34043,6 @@ function readAuditEntries(limit) {
|
|
|
33941
34043
|
return out;
|
|
33942
34044
|
}
|
|
33943
34045
|
|
|
33944
|
-
// src/redact.ts
|
|
33945
|
-
var SECRET_KEY_RE = /^(secret|password|token|api[_-]?key|bearer|authorization|signing[_-]?secret|private[_-]?key|pin|ssn|social[_-]?security[_-]?number|credit[_-]?card|card[_-]?number|cvv|cvc)$/i;
|
|
33946
|
-
var JWT_VALUE_RE = /^eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}$/;
|
|
33947
|
-
var REDACTED = "[REDACTED]";
|
|
33948
|
-
var CIRCULAR = "[CIRCULAR]";
|
|
33949
|
-
var MAX_DEPTH = 32;
|
|
33950
|
-
function isPlainObject3(value) {
|
|
33951
|
-
if (value === null || typeof value !== "object") return false;
|
|
33952
|
-
const proto = Object.getPrototypeOf(value);
|
|
33953
|
-
return proto === Object.prototype || proto === null;
|
|
33954
|
-
}
|
|
33955
|
-
function looksLikeBearerToken(value) {
|
|
33956
|
-
if (typeof value !== "string") return false;
|
|
33957
|
-
if (value.length < 20) return false;
|
|
33958
|
-
return JWT_VALUE_RE.test(value);
|
|
33959
|
-
}
|
|
33960
|
-
function redactInner(value, ancestors, memo, depth) {
|
|
33961
|
-
if (depth > MAX_DEPTH) return CIRCULAR;
|
|
33962
|
-
if (typeof value === "string" && looksLikeBearerToken(value)) return REDACTED;
|
|
33963
|
-
if (value === null || typeof value !== "object") return value;
|
|
33964
|
-
const isArray = Array.isArray(value);
|
|
33965
|
-
if (!isArray && !isPlainObject3(value)) return value;
|
|
33966
|
-
if (ancestors.has(value)) return CIRCULAR;
|
|
33967
|
-
const cached3 = memo.get(value);
|
|
33968
|
-
if (cached3 !== void 0 && cached3.depth <= depth) return cached3.result;
|
|
33969
|
-
ancestors.add(value);
|
|
33970
|
-
let result;
|
|
33971
|
-
if (isArray) {
|
|
33972
|
-
result = value.map((item) => redactInner(item, ancestors, memo, depth + 1));
|
|
33973
|
-
} else {
|
|
33974
|
-
const out = {};
|
|
33975
|
-
for (const [key, val] of Object.entries(value)) {
|
|
33976
|
-
out[key] = SECRET_KEY_RE.test(key) ? REDACTED : redactInner(val, ancestors, memo, depth + 1);
|
|
33977
|
-
}
|
|
33978
|
-
result = out;
|
|
33979
|
-
}
|
|
33980
|
-
ancestors.delete(value);
|
|
33981
|
-
memo.set(value, { depth, result });
|
|
33982
|
-
return result;
|
|
33983
|
-
}
|
|
33984
|
-
function redactSecrets(input) {
|
|
33985
|
-
return redactInner(input, /* @__PURE__ */ new WeakSet(), /* @__PURE__ */ new WeakMap(), 0);
|
|
33986
|
-
}
|
|
33987
|
-
|
|
33988
34046
|
// src/wrapper.ts
|
|
33989
34047
|
function createToolHandler(tool) {
|
|
33990
34048
|
return async (input) => {
|
|
@@ -34102,7 +34160,7 @@ function readAuditLogResource(uri) {
|
|
|
34102
34160
|
}
|
|
34103
34161
|
|
|
34104
34162
|
// src/index.ts
|
|
34105
|
-
var version2 = true ? "0.
|
|
34163
|
+
var version2 = true ? "1.0.0" : createRequire(import.meta.url)("../package.json").version;
|
|
34106
34164
|
var subcommand = process.argv[2];
|
|
34107
34165
|
if (subcommand === "version" || subcommand === "--version") {
|
|
34108
34166
|
console.log(version2);
|
package/package.json
CHANGED
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@yawlabs/lemonsqueezy-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"mcpName": "io.github.YawLabs/lemonsqueezy-mcp",
|
|
5
|
-
"description": "Lemon Squeezy MCP server: stores, orders, subscriptions, license keys, refunds, and webhooks.",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"author": "YawLabs <contact@yaw.sh>",
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/YawLabs/lemonsqueezy-mcp.git"
|
|
11
|
-
},
|
|
12
|
-
"bugs": {
|
|
13
|
-
"url": "https://github.com/YawLabs/lemonsqueezy-mcp/issues"
|
|
14
|
-
},
|
|
15
|
-
"keywords": [
|
|
16
|
-
"lemonsqueezy",
|
|
17
|
-
"lemon-squeezy",
|
|
18
|
-
"mcp",
|
|
19
|
-
"mcp-server",
|
|
20
|
-
"model-context-protocol",
|
|
21
|
-
"ai",
|
|
22
|
-
"agent",
|
|
23
|
-
"claude",
|
|
24
|
-
"claude-code",
|
|
25
|
-
"claude-desktop",
|
|
26
|
-
"payments",
|
|
27
|
-
"subscriptions",
|
|
28
|
-
"refunds",
|
|
29
|
-
"license-keys",
|
|
30
|
-
"licensing",
|
|
31
|
-
"checkout",
|
|
32
|
-
"webhooks",
|
|
33
|
-
"billing",
|
|
34
|
-
"cursor",
|
|
35
|
-
"ai-agents"
|
|
36
|
-
],
|
|
37
|
-
"type": "module",
|
|
38
|
-
"main": "dist/index.js",
|
|
39
|
-
"bin": {
|
|
40
|
-
"lemonsqueezy-mcp": "bin/lemonsqueezy-mcp.mjs"
|
|
41
|
-
},
|
|
42
|
-
"files": [
|
|
43
|
-
"bin/lemonsqueezy-mcp.mjs",
|
|
44
|
-
"dist/index.js",
|
|
45
|
-
"CHANGELOG.md"
|
|
46
|
-
],
|
|
47
|
-
"scripts": {
|
|
48
|
-
"build": "tsc && node build.mjs",
|
|
49
|
-
"dev": "tsc --watch",
|
|
50
|
-
"start": "node dist/index.js",
|
|
51
|
-
"test": "npm run build && node --test-timeout=300000 --test \"dist/**/*.test.js\"",
|
|
52
|
-
"test:integration": "npm run build && node --test-timeout=300000 --test dist/integration/*.test.js",
|
|
53
|
-
"lint": "node scripts/lint.mjs check src/",
|
|
54
|
-
"lint:fix": "node scripts/lint.mjs check --write src/",
|
|
55
|
-
"check:oam": "oam check",
|
|
56
|
-
"build:binary:oam": "node scripts/build-binary.mjs --oam",
|
|
57
|
-
"gen:containerfile": "node scripts/sync-containerfile.mjs",
|
|
58
|
-
"check:containerfile": "node scripts/sync-containerfile.mjs --check",
|
|
59
|
-
"prepublishOnly": "npm run build"
|
|
60
|
-
},
|
|
61
|
-
"overrides": {
|
|
62
|
-
"hono": "^4.13.5"
|
|
63
|
-
},
|
|
64
|
-
"devDependencies": {
|
|
65
|
-
"@biomejs/biome": "^2.4.12",
|
|
66
|
-
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
67
|
-
"@types/node": "^26.1.1",
|
|
68
|
-
"esbuild": "^0.28.1",
|
|
69
|
-
"postject": "^1.0.0-alpha.6",
|
|
70
|
-
"typescript": "^7.0.2",
|
|
71
|
-
"zod": "^4.3.6"
|
|
72
|
-
},
|
|
73
|
-
"engines": {
|
|
74
|
-
"node": ">=22"
|
|
75
|
-
},
|
|
76
|
-
"homepage": "https://yaw.sh/mcp-servers/lemonsqueezy-mcp/"
|
|
77
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@yawlabs/lemonsqueezy-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"mcpName": "io.github.YawLabs/lemonsqueezy-mcp",
|
|
5
|
+
"description": "Lemon Squeezy MCP server: stores, orders, subscriptions, license keys, refunds, and webhooks.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "YawLabs <contact@yaw.sh>",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/YawLabs/lemonsqueezy-mcp.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/YawLabs/lemonsqueezy-mcp/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"lemonsqueezy",
|
|
17
|
+
"lemon-squeezy",
|
|
18
|
+
"mcp",
|
|
19
|
+
"mcp-server",
|
|
20
|
+
"model-context-protocol",
|
|
21
|
+
"ai",
|
|
22
|
+
"agent",
|
|
23
|
+
"claude",
|
|
24
|
+
"claude-code",
|
|
25
|
+
"claude-desktop",
|
|
26
|
+
"payments",
|
|
27
|
+
"subscriptions",
|
|
28
|
+
"refunds",
|
|
29
|
+
"license-keys",
|
|
30
|
+
"licensing",
|
|
31
|
+
"checkout",
|
|
32
|
+
"webhooks",
|
|
33
|
+
"billing",
|
|
34
|
+
"cursor",
|
|
35
|
+
"ai-agents"
|
|
36
|
+
],
|
|
37
|
+
"type": "module",
|
|
38
|
+
"main": "dist/index.js",
|
|
39
|
+
"bin": {
|
|
40
|
+
"lemonsqueezy-mcp": "bin/lemonsqueezy-mcp.mjs"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"bin/lemonsqueezy-mcp.mjs",
|
|
44
|
+
"dist/index.js",
|
|
45
|
+
"CHANGELOG.md"
|
|
46
|
+
],
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc && node build.mjs",
|
|
49
|
+
"dev": "tsc --watch",
|
|
50
|
+
"start": "node dist/index.js",
|
|
51
|
+
"test": "npm run build && node --test-timeout=300000 --test \"dist/**/*.test.js\"",
|
|
52
|
+
"test:integration": "node scripts/require-integration-env.mjs && npm run build && node --test-timeout=300000 --test dist/integration/*.test.js",
|
|
53
|
+
"lint": "node scripts/lint.mjs check src/",
|
|
54
|
+
"lint:fix": "node scripts/lint.mjs check --write src/",
|
|
55
|
+
"check:oam": "oam check",
|
|
56
|
+
"build:binary:oam": "node scripts/build-binary.mjs --oam",
|
|
57
|
+
"gen:containerfile": "node scripts/sync-containerfile.mjs",
|
|
58
|
+
"check:containerfile": "node scripts/sync-containerfile.mjs --check",
|
|
59
|
+
"prepublishOnly": "npm run build"
|
|
60
|
+
},
|
|
61
|
+
"overrides": {
|
|
62
|
+
"hono": "^4.13.5"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@biomejs/biome": "^2.4.12",
|
|
66
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
67
|
+
"@types/node": "^26.1.1",
|
|
68
|
+
"esbuild": "^0.28.1",
|
|
69
|
+
"postject": "^1.0.0-alpha.6",
|
|
70
|
+
"typescript": "^7.0.2",
|
|
71
|
+
"zod": "^4.3.6"
|
|
72
|
+
},
|
|
73
|
+
"engines": {
|
|
74
|
+
"node": ">=22"
|
|
75
|
+
},
|
|
76
|
+
"homepage": "https://yaw.sh/mcp-servers/lemonsqueezy-mcp/"
|
|
77
|
+
}
|