@sakupa/mcp 0.7.1 → 0.7.3
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/bin.js +23 -13
- package/dist/index.js +23 -13
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -128,7 +128,7 @@ var FORBIDDEN_PATH_SEGMENTS = [
|
|
|
128
128
|
var ALLOWED_HIDDEN_PATHS = [".well-known/"];
|
|
129
129
|
|
|
130
130
|
// ../core/dist/domain/version.js
|
|
131
|
-
var SAKUPA_MCP_VERSION = "0.7.
|
|
131
|
+
var SAKUPA_MCP_VERSION = "0.7.3";
|
|
132
132
|
|
|
133
133
|
// ../core/dist/domain/errors.js
|
|
134
134
|
var HTTP_STATUS = {
|
|
@@ -467,6 +467,9 @@ var WEBHOOK_PROCESSING_LEASE_MS = 5 * 60 * 1e3;
|
|
|
467
467
|
|
|
468
468
|
// src/config.ts
|
|
469
469
|
var TEST_API_BASE_URL = "https://api-test.sakupa.com";
|
|
470
|
+
function previewHostPatternFor(apiBaseUrl) {
|
|
471
|
+
return apiBaseUrl === TEST_API_BASE_URL ? "{shortId}-test.sakupa.com" : "{shortId}.sakupa.com";
|
|
472
|
+
}
|
|
470
473
|
function loadMcpRuntimeConfig(env = process.env, cwd = process.cwd()) {
|
|
471
474
|
const apiBaseUrl = (env["SAKUPA_API_URL"] ?? DEFAULT_API_BASE_URL).replace(/\/+$/, "");
|
|
472
475
|
const projectDir = env["SAKUPA_PROJECT_DIR"] ?? cwd;
|
|
@@ -1394,6 +1397,7 @@ async function uploadAll(ctx, targets, files, outputAbs) {
|
|
|
1394
1397
|
return targets.length;
|
|
1395
1398
|
}
|
|
1396
1399
|
function registerTools(server, ctx) {
|
|
1400
|
+
const previewHostPattern = previewHostPatternFor(ctx.apiBaseUrl);
|
|
1397
1401
|
server.registerTool(
|
|
1398
1402
|
"analyze_site",
|
|
1399
1403
|
{
|
|
@@ -1427,7 +1431,7 @@ Next action: ${analysis.suggestedNextAction}`,
|
|
|
1427
1431
|
server.registerTool(
|
|
1428
1432
|
"deploy_site",
|
|
1429
1433
|
{
|
|
1430
|
-
description: `Deploy the local static output to Sakupa. First deploy creates a free temporary site (valid ${FREE_SITE_TTL_HOURS}h, public URL like https
|
|
1434
|
+
description: `Deploy the local static output to Sakupa. First deploy creates a free temporary site (valid ${FREE_SITE_TTL_HOURS}h, public URL like https://${previewHostPattern}) and stores the management credential in .sakupa/site.json. Later runs update the existing site (free sites also refresh their validity; subscribed sites are permanent). Runs analyze_site first and refuses to upload source projects, secrets, .env files, archives, media or server code. Never uploads anything when the analysis says the project is not deployable.`,
|
|
1431
1435
|
outputSchema: STRUCTURED_TOOL_OUTPUT_SCHEMA,
|
|
1432
1436
|
annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: true },
|
|
1433
1437
|
inputSchema: {
|
|
@@ -1610,7 +1614,7 @@ Free sites stay live for ${FREE_SITE_TTL_HOURS} hours after each deploy or refre
|
|
|
1610
1614
|
server.registerTool(
|
|
1611
1615
|
"subscribe_site",
|
|
1612
1616
|
{
|
|
1613
|
-
description: `Create a Stripe Checkout link that subscribes THIS site to a Sakupa Hosting monthly plan (${planCatalog()}). Paying makes the site PERMANENT on its {
|
|
1617
|
+
description: `Create a Stripe Checkout link that subscribes THIS site to a Sakupa Hosting monthly plan (${planCatalog()}). Paying makes the site PERMANENT on its ${previewHostPattern} URL \u2014 no more 24h expiry; that is the core value of paying. Binding a custom domain afterwards (bind_domain) is an optional included extra and requires DNS control of that domain. Owner-only: requires this project's site credential (.sakupa/site.json) \u2014 deploy_site first. If the site outgrows its plan, Sakupa shows an over-limit notice and never changes billing automatically. The owner can explicitly choose another plan through Stripe Customer Portal. Card details are entered only on the Stripe-hosted page \u2014 never through the AI tool. Opening and completing Stripe Checkout is the final subscription confirmation.`,
|
|
1614
1618
|
outputSchema: STRUCTURED_TOOL_OUTPUT_SCHEMA,
|
|
1615
1619
|
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: true },
|
|
1616
1620
|
inputSchema: {
|
|
@@ -1655,7 +1659,7 @@ Once payment confirms, the site becomes permanent on its current URL. Binding a
|
|
|
1655
1659
|
server.registerTool(
|
|
1656
1660
|
"bind_domain",
|
|
1657
1661
|
{
|
|
1658
|
-
description:
|
|
1662
|
+
description: `Bind a custom domain to this subscribed site \u2014 an OPTIONAL extra serving surface; the permanent ${previewHostPattern} URL keeps working alongside it. The binding unit is the APEX domain: binding example.com automatically includes www.example.com (both serve the same content, one apex TXT verification covers both), and one site binds at most ONE apex domain \u2014 a second domain needs a second subscribed site. Requires an ACTIVE subscription (subscribe_site). Ownership is proven ONLY by DNS control of the apex \u2014 payment never grants ownership. A binding request never reserves the domain: whoever proves DNS control first gets it, and unverified requests expire after 72 hours. Call again with verificationId to check progress.`,
|
|
1659
1663
|
outputSchema: STRUCTURED_TOOL_OUTPUT_SCHEMA,
|
|
1660
1664
|
annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: true },
|
|
1661
1665
|
inputSchema: {
|
|
@@ -2288,28 +2292,34 @@ var FetchTransport = class {
|
|
|
2288
2292
|
};
|
|
2289
2293
|
|
|
2290
2294
|
// src/server.ts
|
|
2291
|
-
var
|
|
2295
|
+
var instructionsFor = (hostPattern) => `Sakupa publishes AI-made static websites. AI-made pages, live in seconds.
|
|
2292
2296
|
|
|
2293
2297
|
Workflow:
|
|
2294
2298
|
1. analyze_site \u2014 check whether this project has deployable static output. If a build is needed
|
|
2295
2299
|
(Vite/Vue/React/Svelte/Astro/Next static export/Nuxt generate), run the build LOCALLY first,
|
|
2296
2300
|
then re-run analyze_site.
|
|
2297
2301
|
2. deploy_site \u2014 uploads ONLY the built static output. The first deploy creates a free temporary
|
|
2298
|
-
site (public URL {
|
|
2302
|
+
site (public URL ${hostPattern}, valid 24 hours, free banner shown) and stores the
|
|
2299
2303
|
management credential in .sakupa/site.json. Deploying again updates the site and refreshes
|
|
2300
|
-
its validity; refresh_site extends validity without uploading
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
+
its validity; refresh_site extends validity without uploading; site_status shows the
|
|
2305
|
+
current deployment and serving state at any time.
|
|
2306
|
+
3. To make the site PERMANENT, subscribe it to a monthly hosting plan (list_billing_plans
|
|
2307
|
+
shows the catalog; subscribe_site -> Stripe-hosted checkout;
|
|
2308
|
+
water/personal/share/business). Paying makes the
|
|
2309
|
+
${hostPattern} URL permanent \u2014 that is what payment buys. Usage over the chosen plan
|
|
2304
2310
|
shows an over-limit notice by default. An external AI may periodically query usage and
|
|
2305
2311
|
recommend a plan, but Sakupa never changes a subscription automatically.
|
|
2306
2312
|
4. Optionally bind a custom domain to the subscribed site (bind_domain): an included extra
|
|
2307
2313
|
serving surface alongside the permanent URL. Ownership is proven only by DNS control; the
|
|
2308
2314
|
first verified request wins; unverified requests expire after 72 hours. billing_status,
|
|
2309
|
-
|
|
2310
|
-
lifecycle
|
|
2315
|
+
change_subscription_plan, manage_billing and recover_domain_site manage the paid
|
|
2316
|
+
lifecycle; unbind_domain removes the custom domain (the permanent URL keeps serving) and
|
|
2317
|
+
delete_site tears the whole site down after explicit confirmation.
|
|
2318
|
+
Plan changes are confirmed only on Stripe and synchronized by Stripe webhook.
|
|
2311
2319
|
A cancellation keeps the site paid through the current period. Sakupa reverts it to a free
|
|
2312
2320
|
24h site and removes paid data after Stripe sends the signed final-cancellation webhook.
|
|
2321
|
+
5. create_support_ticket (subscribed sites) opens a support ticket; report_bug sends a
|
|
2322
|
+
sanitized diagnostic report after the user explicitly confirms it.
|
|
2313
2323
|
|
|
2314
2324
|
Safety boundaries:
|
|
2315
2325
|
- Static output only: no SSR, API routes, middleware, server actions, databases or online builds.
|
|
@@ -2326,7 +2336,7 @@ function createSakupaMcpServer(opts) {
|
|
|
2326
2336
|
);
|
|
2327
2337
|
const server = new McpServer(
|
|
2328
2338
|
{ name: "sakupa", version: MCP_VERSION },
|
|
2329
|
-
{ instructions:
|
|
2339
|
+
{ instructions: instructionsFor(previewHostPatternFor(opts.apiBaseUrl)) }
|
|
2330
2340
|
);
|
|
2331
2341
|
registerTools(server, {
|
|
2332
2342
|
client,
|
package/dist/index.js
CHANGED
|
@@ -123,7 +123,7 @@ var FORBIDDEN_PATH_SEGMENTS = [
|
|
|
123
123
|
var ALLOWED_HIDDEN_PATHS = [".well-known/"];
|
|
124
124
|
|
|
125
125
|
// ../core/dist/domain/version.js
|
|
126
|
-
var SAKUPA_MCP_VERSION = "0.7.
|
|
126
|
+
var SAKUPA_MCP_VERSION = "0.7.3";
|
|
127
127
|
|
|
128
128
|
// ../core/dist/domain/errors.js
|
|
129
129
|
var HTTP_STATUS = {
|
|
@@ -466,6 +466,9 @@ var CLIENT_TYPE = "sakupa-mcp";
|
|
|
466
466
|
|
|
467
467
|
// src/config.ts
|
|
468
468
|
var TEST_API_BASE_URL = "https://api-test.sakupa.com";
|
|
469
|
+
function previewHostPatternFor(apiBaseUrl) {
|
|
470
|
+
return apiBaseUrl === TEST_API_BASE_URL ? "{shortId}-test.sakupa.com" : "{shortId}.sakupa.com";
|
|
471
|
+
}
|
|
469
472
|
function loadMcpRuntimeConfig(env = process.env, cwd = process.cwd()) {
|
|
470
473
|
const apiBaseUrl = (env["SAKUPA_API_URL"] ?? DEFAULT_API_BASE_URL).replace(/\/+$/, "");
|
|
471
474
|
const projectDir = env["SAKUPA_PROJECT_DIR"] ?? cwd;
|
|
@@ -1456,6 +1459,7 @@ async function uploadAll(ctx, targets, files, outputAbs) {
|
|
|
1456
1459
|
return targets.length;
|
|
1457
1460
|
}
|
|
1458
1461
|
function registerTools(server, ctx) {
|
|
1462
|
+
const previewHostPattern = previewHostPatternFor(ctx.apiBaseUrl);
|
|
1459
1463
|
server.registerTool(
|
|
1460
1464
|
"analyze_site",
|
|
1461
1465
|
{
|
|
@@ -1489,7 +1493,7 @@ Next action: ${analysis.suggestedNextAction}`,
|
|
|
1489
1493
|
server.registerTool(
|
|
1490
1494
|
"deploy_site",
|
|
1491
1495
|
{
|
|
1492
|
-
description: `Deploy the local static output to Sakupa. First deploy creates a free temporary site (valid ${FREE_SITE_TTL_HOURS}h, public URL like https
|
|
1496
|
+
description: `Deploy the local static output to Sakupa. First deploy creates a free temporary site (valid ${FREE_SITE_TTL_HOURS}h, public URL like https://${previewHostPattern}) and stores the management credential in .sakupa/site.json. Later runs update the existing site (free sites also refresh their validity; subscribed sites are permanent). Runs analyze_site first and refuses to upload source projects, secrets, .env files, archives, media or server code. Never uploads anything when the analysis says the project is not deployable.`,
|
|
1493
1497
|
outputSchema: STRUCTURED_TOOL_OUTPUT_SCHEMA,
|
|
1494
1498
|
annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: true },
|
|
1495
1499
|
inputSchema: {
|
|
@@ -1672,7 +1676,7 @@ Free sites stay live for ${FREE_SITE_TTL_HOURS} hours after each deploy or refre
|
|
|
1672
1676
|
server.registerTool(
|
|
1673
1677
|
"subscribe_site",
|
|
1674
1678
|
{
|
|
1675
|
-
description: `Create a Stripe Checkout link that subscribes THIS site to a Sakupa Hosting monthly plan (${planCatalog()}). Paying makes the site PERMANENT on its {
|
|
1679
|
+
description: `Create a Stripe Checkout link that subscribes THIS site to a Sakupa Hosting monthly plan (${planCatalog()}). Paying makes the site PERMANENT on its ${previewHostPattern} URL \u2014 no more 24h expiry; that is the core value of paying. Binding a custom domain afterwards (bind_domain) is an optional included extra and requires DNS control of that domain. Owner-only: requires this project's site credential (.sakupa/site.json) \u2014 deploy_site first. If the site outgrows its plan, Sakupa shows an over-limit notice and never changes billing automatically. The owner can explicitly choose another plan through Stripe Customer Portal. Card details are entered only on the Stripe-hosted page \u2014 never through the AI tool. Opening and completing Stripe Checkout is the final subscription confirmation.`,
|
|
1676
1680
|
outputSchema: STRUCTURED_TOOL_OUTPUT_SCHEMA,
|
|
1677
1681
|
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: true },
|
|
1678
1682
|
inputSchema: {
|
|
@@ -1717,7 +1721,7 @@ Once payment confirms, the site becomes permanent on its current URL. Binding a
|
|
|
1717
1721
|
server.registerTool(
|
|
1718
1722
|
"bind_domain",
|
|
1719
1723
|
{
|
|
1720
|
-
description:
|
|
1724
|
+
description: `Bind a custom domain to this subscribed site \u2014 an OPTIONAL extra serving surface; the permanent ${previewHostPattern} URL keeps working alongside it. The binding unit is the APEX domain: binding example.com automatically includes www.example.com (both serve the same content, one apex TXT verification covers both), and one site binds at most ONE apex domain \u2014 a second domain needs a second subscribed site. Requires an ACTIVE subscription (subscribe_site). Ownership is proven ONLY by DNS control of the apex \u2014 payment never grants ownership. A binding request never reserves the domain: whoever proves DNS control first gets it, and unverified requests expire after 72 hours. Call again with verificationId to check progress.`,
|
|
1721
1725
|
outputSchema: STRUCTURED_TOOL_OUTPUT_SCHEMA,
|
|
1722
1726
|
annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: true },
|
|
1723
1727
|
inputSchema: {
|
|
@@ -2281,28 +2285,34 @@ function registerBillingTools(server, ctx) {
|
|
|
2281
2285
|
}
|
|
2282
2286
|
|
|
2283
2287
|
// src/server.ts
|
|
2284
|
-
var
|
|
2288
|
+
var instructionsFor = (hostPattern) => `Sakupa publishes AI-made static websites. AI-made pages, live in seconds.
|
|
2285
2289
|
|
|
2286
2290
|
Workflow:
|
|
2287
2291
|
1. analyze_site \u2014 check whether this project has deployable static output. If a build is needed
|
|
2288
2292
|
(Vite/Vue/React/Svelte/Astro/Next static export/Nuxt generate), run the build LOCALLY first,
|
|
2289
2293
|
then re-run analyze_site.
|
|
2290
2294
|
2. deploy_site \u2014 uploads ONLY the built static output. The first deploy creates a free temporary
|
|
2291
|
-
site (public URL {
|
|
2295
|
+
site (public URL ${hostPattern}, valid 24 hours, free banner shown) and stores the
|
|
2292
2296
|
management credential in .sakupa/site.json. Deploying again updates the site and refreshes
|
|
2293
|
-
its validity; refresh_site extends validity without uploading
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
+
its validity; refresh_site extends validity without uploading; site_status shows the
|
|
2298
|
+
current deployment and serving state at any time.
|
|
2299
|
+
3. To make the site PERMANENT, subscribe it to a monthly hosting plan (list_billing_plans
|
|
2300
|
+
shows the catalog; subscribe_site -> Stripe-hosted checkout;
|
|
2301
|
+
water/personal/share/business). Paying makes the
|
|
2302
|
+
${hostPattern} URL permanent \u2014 that is what payment buys. Usage over the chosen plan
|
|
2297
2303
|
shows an over-limit notice by default. An external AI may periodically query usage and
|
|
2298
2304
|
recommend a plan, but Sakupa never changes a subscription automatically.
|
|
2299
2305
|
4. Optionally bind a custom domain to the subscribed site (bind_domain): an included extra
|
|
2300
2306
|
serving surface alongside the permanent URL. Ownership is proven only by DNS control; the
|
|
2301
2307
|
first verified request wins; unverified requests expire after 72 hours. billing_status,
|
|
2302
|
-
|
|
2303
|
-
lifecycle
|
|
2308
|
+
change_subscription_plan, manage_billing and recover_domain_site manage the paid
|
|
2309
|
+
lifecycle; unbind_domain removes the custom domain (the permanent URL keeps serving) and
|
|
2310
|
+
delete_site tears the whole site down after explicit confirmation.
|
|
2311
|
+
Plan changes are confirmed only on Stripe and synchronized by Stripe webhook.
|
|
2304
2312
|
A cancellation keeps the site paid through the current period. Sakupa reverts it to a free
|
|
2305
2313
|
24h site and removes paid data after Stripe sends the signed final-cancellation webhook.
|
|
2314
|
+
5. create_support_ticket (subscribed sites) opens a support ticket; report_bug sends a
|
|
2315
|
+
sanitized diagnostic report after the user explicitly confirms it.
|
|
2306
2316
|
|
|
2307
2317
|
Safety boundaries:
|
|
2308
2318
|
- Static output only: no SSR, API routes, middleware, server actions, databases or online builds.
|
|
@@ -2319,7 +2329,7 @@ function createSakupaMcpServer(opts) {
|
|
|
2319
2329
|
);
|
|
2320
2330
|
const server = new McpServer(
|
|
2321
2331
|
{ name: "sakupa", version: MCP_VERSION },
|
|
2322
|
-
{ instructions:
|
|
2332
|
+
{ instructions: instructionsFor(previewHostPatternFor(opts.apiBaseUrl)) }
|
|
2323
2333
|
);
|
|
2324
2334
|
registerTools(server, {
|
|
2325
2335
|
client,
|