@vibetocloud/mcp 1.0.0 → 1.0.2
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/index.js +187 -53
- package/package.json +1 -1
- package/skills/skills/vibetocloud-onboard/SKILL.md +28 -0
package/dist/index.js
CHANGED
|
@@ -57455,25 +57455,24 @@ var ValidateRequestGuard = class {
|
|
|
57455
57455
|
}
|
|
57456
57456
|
async canActivate(context) {
|
|
57457
57457
|
const req = context.switchToHttp().getRequest();
|
|
57458
|
+
const authHeader = req.headers.authorization;
|
|
57459
|
+
if (authHeader?.startsWith("Bearer ")) {
|
|
57460
|
+
const token = authHeader.slice(7);
|
|
57461
|
+
try {
|
|
57462
|
+
const publicKey = await this.publicKeyCache.get();
|
|
57463
|
+
const payload = import_jsonwebtoken.default.verify(token, publicKey, { algorithms: ["RS256"] });
|
|
57464
|
+
req.auth = { kind: "user", payload };
|
|
57465
|
+
return true;
|
|
57466
|
+
} catch {
|
|
57467
|
+
}
|
|
57468
|
+
}
|
|
57458
57469
|
const internalServiceKey = process.env["INTERNAL_SERVICE_KEY"];
|
|
57459
57470
|
const sentKey = req.headers["x-internal-secret"] ?? req.headers["x-service-key"];
|
|
57460
57471
|
if (internalServiceKey && sentKey === internalServiceKey) {
|
|
57461
57472
|
req.auth = { kind: "internal" };
|
|
57462
57473
|
return true;
|
|
57463
57474
|
}
|
|
57464
|
-
|
|
57465
|
-
if (!authHeader?.startsWith("Bearer ")) {
|
|
57466
|
-
throw new import_common3.UnauthorizedException("Missing or invalid Authorization header");
|
|
57467
|
-
}
|
|
57468
|
-
const token = authHeader.slice(7);
|
|
57469
|
-
try {
|
|
57470
|
-
const publicKey = await this.publicKeyCache.get();
|
|
57471
|
-
const payload = import_jsonwebtoken.default.verify(token, publicKey, { algorithms: ["RS256"] });
|
|
57472
|
-
req.auth = { kind: "user", payload };
|
|
57473
|
-
return true;
|
|
57474
|
-
} catch {
|
|
57475
|
-
throw new import_common3.UnauthorizedException("Invalid or expired token");
|
|
57476
|
-
}
|
|
57475
|
+
throw new import_common3.UnauthorizedException("Missing or invalid Authorization header");
|
|
57477
57476
|
}
|
|
57478
57477
|
};
|
|
57479
57478
|
ValidateRequestGuard = __decorateClass([
|
|
@@ -57626,6 +57625,7 @@ var DeployClient = class {
|
|
|
57626
57625
|
return null;
|
|
57627
57626
|
}
|
|
57628
57627
|
}
|
|
57628
|
+
/** First page only (default page size) — callers needing more should call the history endpoint directly with `take`/`cursor`. */
|
|
57629
57629
|
async history(appId) {
|
|
57630
57630
|
try {
|
|
57631
57631
|
const res = await fetch(`${this.baseUrl}/deploy/history/${encodeURIComponent(appId)}`, {
|
|
@@ -57636,7 +57636,7 @@ var DeployClient = class {
|
|
|
57636
57636
|
return [];
|
|
57637
57637
|
}
|
|
57638
57638
|
const json = await res.json();
|
|
57639
|
-
return json.data ?? [];
|
|
57639
|
+
return json.data?.items ?? [];
|
|
57640
57640
|
} catch {
|
|
57641
57641
|
return [];
|
|
57642
57642
|
}
|
|
@@ -57672,6 +57672,21 @@ var DeployClient = class {
|
|
|
57672
57672
|
return null;
|
|
57673
57673
|
}
|
|
57674
57674
|
}
|
|
57675
|
+
async cancel(options) {
|
|
57676
|
+
try {
|
|
57677
|
+
const res = await fetch(`${this.baseUrl}/deploy/cancel/${encodeURIComponent(options.buildId)}`, {
|
|
57678
|
+
method: "POST",
|
|
57679
|
+
headers: this.headers
|
|
57680
|
+
});
|
|
57681
|
+
if (!res.ok) {
|
|
57682
|
+
return null;
|
|
57683
|
+
}
|
|
57684
|
+
const json = await res.json();
|
|
57685
|
+
return json.data;
|
|
57686
|
+
} catch {
|
|
57687
|
+
return null;
|
|
57688
|
+
}
|
|
57689
|
+
}
|
|
57675
57690
|
async restoreBackup(appId, backupId, environment) {
|
|
57676
57691
|
try {
|
|
57677
57692
|
const res = await fetch(`${this.baseUrl}/applications/${encodeURIComponent(appId)}/backups/${encodeURIComponent(backupId)}/restore`, {
|
|
@@ -57715,6 +57730,9 @@ var UserClient = class {
|
|
|
57715
57730
|
getUser(id) {
|
|
57716
57731
|
return this.request("GET", `/users/${id}`);
|
|
57717
57732
|
}
|
|
57733
|
+
getUserByEmail(email2) {
|
|
57734
|
+
return this.request("GET", `/users?email=${encodeURIComponent(email2)}`);
|
|
57735
|
+
}
|
|
57718
57736
|
createUser(options) {
|
|
57719
57737
|
return this.request("POST", "/users", options);
|
|
57720
57738
|
}
|
|
@@ -57864,6 +57882,14 @@ var AccountClient = class {
|
|
|
57864
57882
|
const env = environments.length ? `&environments=${encodeURIComponent(environments.join(","))}` : "";
|
|
57865
57883
|
return this.request("GET", `/entitlements/active?orgId=${encodeURIComponent(orgId)}${env}`);
|
|
57866
57884
|
}
|
|
57885
|
+
/** Per-application capabilities (environments/backup tier scoped to one application). */
|
|
57886
|
+
getAppActiveCapabilities(orgId, appId, environments = []) {
|
|
57887
|
+
const env = environments.length ? `&environments=${encodeURIComponent(environments.join(","))}` : "";
|
|
57888
|
+
return this.request(
|
|
57889
|
+
"GET",
|
|
57890
|
+
`/entitlements/app-active?orgId=${encodeURIComponent(orgId)}&appId=${encodeURIComponent(appId)}${env}`
|
|
57891
|
+
);
|
|
57892
|
+
}
|
|
57867
57893
|
/** List purchasable environments (staging/production) with their Stripe prices. */
|
|
57868
57894
|
listCatalogEnvironments() {
|
|
57869
57895
|
return this.request("GET", "/catalog/environments").then((d) => d ?? []);
|
|
@@ -57894,6 +57920,16 @@ var AccountClient = class {
|
|
|
57894
57920
|
delta
|
|
57895
57921
|
}).then((d) => d !== null);
|
|
57896
57922
|
}
|
|
57923
|
+
/**
|
|
57924
|
+
* Adjust the org's quantity-billed application-count item by ±1.
|
|
57925
|
+
* Called by application-service on application create / delete (Pay-as-you-go only).
|
|
57926
|
+
*/
|
|
57927
|
+
adjustApplicationQuantity(orgId, delta) {
|
|
57928
|
+
return this.request("POST", "/entitlements/application-quantity", {
|
|
57929
|
+
orgId,
|
|
57930
|
+
delta
|
|
57931
|
+
}).then((d) => d !== null);
|
|
57932
|
+
}
|
|
57897
57933
|
};
|
|
57898
57934
|
|
|
57899
57935
|
// libs/shared/src/utils/validate-identifier.ts
|
|
@@ -57905,6 +57941,43 @@ var ENVIRONMENT_NAMES = ["dev", "staging", "production"];
|
|
|
57905
57941
|
// libs/shared/src/utils/org-ownership.ts
|
|
57906
57942
|
var import_common6 = __toESM(require_common2());
|
|
57907
57943
|
|
|
57944
|
+
// libs/shared/src/utils/jwt-lifetime.ts
|
|
57945
|
+
function decodeJwtLifetime(token) {
|
|
57946
|
+
const parts = token.split(".");
|
|
57947
|
+
if (parts.length !== 3 || !parts[1]) {
|
|
57948
|
+
return null;
|
|
57949
|
+
}
|
|
57950
|
+
try {
|
|
57951
|
+
const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
|
|
57952
|
+
const { iat, exp } = payload;
|
|
57953
|
+
if (typeof iat !== "number" || typeof exp !== "number") {
|
|
57954
|
+
return null;
|
|
57955
|
+
}
|
|
57956
|
+
return { iat, exp };
|
|
57957
|
+
} catch {
|
|
57958
|
+
return null;
|
|
57959
|
+
}
|
|
57960
|
+
}
|
|
57961
|
+
function isTokenDueForRefresh(token, nowMs = Date.now()) {
|
|
57962
|
+
const lifetime = decodeJwtLifetime(token);
|
|
57963
|
+
if (!lifetime) {
|
|
57964
|
+
return false;
|
|
57965
|
+
}
|
|
57966
|
+
const nowSeconds = nowMs / 1e3;
|
|
57967
|
+
const halfLife = lifetime.iat + (lifetime.exp - lifetime.iat) / 2;
|
|
57968
|
+
return nowSeconds > halfLife && nowSeconds < lifetime.exp;
|
|
57969
|
+
}
|
|
57970
|
+
|
|
57971
|
+
// apps/mcp-server/src/lib/token-refresh.ts
|
|
57972
|
+
var authClient = new AuthClient(config2.services.authServiceUrl);
|
|
57973
|
+
async function maybeRefreshToken(token) {
|
|
57974
|
+
if (!isTokenDueForRefresh(token)) {
|
|
57975
|
+
return null;
|
|
57976
|
+
}
|
|
57977
|
+
const result = await authClient.refresh({ token });
|
|
57978
|
+
return result?.token ?? null;
|
|
57979
|
+
}
|
|
57980
|
+
|
|
57908
57981
|
// apps/mcp-server/src/tools/account.ts
|
|
57909
57982
|
var client = new AccountClient(config2.services.accountServiceUrl);
|
|
57910
57983
|
var orgRegisterTool = {
|
|
@@ -58092,7 +58165,7 @@ var tools2 = [
|
|
|
58092
58165
|
];
|
|
58093
58166
|
|
|
58094
58167
|
// apps/mcp-server/src/tools/auth.ts
|
|
58095
|
-
var
|
|
58168
|
+
var authClient2 = new AuthClient(config2.services.authServiceUrl);
|
|
58096
58169
|
var orgAuthenticateTool = {
|
|
58097
58170
|
name: "org_authenticate",
|
|
58098
58171
|
description: "Verify an existing session token. Returns the authenticated user and organisation. Use this to confirm a stored token is still valid before making other API calls.",
|
|
@@ -58112,7 +58185,7 @@ async function handleOrgAuthenticate(args) {
|
|
|
58112
58185
|
if (!token) {
|
|
58113
58186
|
return fail({ status: 401, message: "Please sign in first. Use org_request_otp and org_verify_otp to authenticate." });
|
|
58114
58187
|
}
|
|
58115
|
-
const result = await
|
|
58188
|
+
const result = await authClient2.verify({ token });
|
|
58116
58189
|
if (!result) {
|
|
58117
58190
|
return fail({ status: 401, message: "Your session has expired or is invalid. Please sign in again with org_request_otp." });
|
|
58118
58191
|
}
|
|
@@ -58422,9 +58495,43 @@ ${tail}`;
|
|
|
58422
58495
|
}]
|
|
58423
58496
|
};
|
|
58424
58497
|
}
|
|
58498
|
+
var orgDeployCancelTool = {
|
|
58499
|
+
name: "org_deploy_cancel",
|
|
58500
|
+
description: 'Cancel a deployment that is currently running. Only works while the build is in the deploy phase; the build is marked failed with reason "Deployment cancelled by user".',
|
|
58501
|
+
inputSchema: {
|
|
58502
|
+
type: "object",
|
|
58503
|
+
properties: {
|
|
58504
|
+
token: { type: "string", description: "JWT session token from org_verify_otp" },
|
|
58505
|
+
buildId: { type: "string", description: "Build ID returned by org_deploy" }
|
|
58506
|
+
},
|
|
58507
|
+
required: ["token", "buildId"]
|
|
58508
|
+
}
|
|
58509
|
+
};
|
|
58510
|
+
async function handleOrgDeployCancel(args) {
|
|
58511
|
+
const token = args["token"];
|
|
58512
|
+
if (!token) {
|
|
58513
|
+
return notAuthenticatedResult();
|
|
58514
|
+
}
|
|
58515
|
+
const client3 = new DeployClient(config2.services.deployServiceUrl, token);
|
|
58516
|
+
const build = await client3.cancel({ buildId: args["buildId"] });
|
|
58517
|
+
if (!build) {
|
|
58518
|
+
return fail({ status: 404, message: "No cancellable deployment found for this build \u2014 it may have already finished, or not reached the deploy phase yet." });
|
|
58519
|
+
}
|
|
58520
|
+
return {
|
|
58521
|
+
content: [{
|
|
58522
|
+
type: "text",
|
|
58523
|
+
text: JSON.stringify({
|
|
58524
|
+
success: true,
|
|
58525
|
+
data: { id: build.id, status: build.status, message: 'Cancellation requested. Poll org_deploy_status \u2014 the build will end as failed with reason "Deployment cancelled by user".' },
|
|
58526
|
+
error: null
|
|
58527
|
+
})
|
|
58528
|
+
}]
|
|
58529
|
+
};
|
|
58530
|
+
}
|
|
58425
58531
|
var tools5 = [
|
|
58426
58532
|
{ definition: orgDeployTool, handle: handleOrgDeploy },
|
|
58427
|
-
{ definition: orgDeployStatusTool, handle: handleOrgDeployStatus }
|
|
58533
|
+
{ definition: orgDeployStatusTool, handle: handleOrgDeployStatus },
|
|
58534
|
+
{ definition: orgDeployCancelTool, handle: handleOrgDeployCancel }
|
|
58428
58535
|
];
|
|
58429
58536
|
|
|
58430
58537
|
// apps/mcp-server/src/tools/dev-sync.ts
|
|
@@ -58556,37 +58663,35 @@ var orgSetupGitCredentialsTool = {
|
|
|
58556
58663
|
inputSchema: {
|
|
58557
58664
|
type: "object",
|
|
58558
58665
|
properties: {
|
|
58559
|
-
|
|
58560
|
-
type: "string",
|
|
58561
|
-
description: "ID of the user to generate the credential for"
|
|
58562
|
-
},
|
|
58563
|
-
orgId: {
|
|
58666
|
+
token: {
|
|
58564
58667
|
type: "string",
|
|
58565
|
-
description: "
|
|
58668
|
+
description: "JWT session token from org_verify_otp"
|
|
58566
58669
|
},
|
|
58567
58670
|
label: {
|
|
58568
58671
|
type: "string",
|
|
58569
58672
|
description: 'Label to identify this credential, e.g. "laptop" or "work" (default: "default")'
|
|
58570
58673
|
}
|
|
58571
58674
|
},
|
|
58572
|
-
required: ["
|
|
58675
|
+
required: ["token"]
|
|
58573
58676
|
}
|
|
58574
58677
|
};
|
|
58575
58678
|
async function handleOrgSetupGitCredentials(args) {
|
|
58576
|
-
const
|
|
58577
|
-
|
|
58679
|
+
const sessionToken = args["token"];
|
|
58680
|
+
if (!sessionToken) {
|
|
58681
|
+
return notAuthenticatedResult();
|
|
58682
|
+
}
|
|
58578
58683
|
const label = args["label"] ?? "default";
|
|
58579
58684
|
try {
|
|
58580
58685
|
const response = await fetch(`${config2.services.userServiceUrl}/git-credentials`, {
|
|
58581
58686
|
method: "POST",
|
|
58582
|
-
headers:
|
|
58583
|
-
body: JSON.stringify({
|
|
58687
|
+
headers: authHeaders(sessionToken),
|
|
58688
|
+
body: JSON.stringify({ label })
|
|
58584
58689
|
});
|
|
58585
58690
|
if (!response.ok) {
|
|
58586
58691
|
return fail({ status: response.status, message: "Failed to create git credential" });
|
|
58587
58692
|
}
|
|
58588
58693
|
const json = await response.json();
|
|
58589
|
-
const
|
|
58694
|
+
const credentialToken = json.data.token;
|
|
58590
58695
|
const gitHost = config2.services.applicationServiceUrl.replace(/^https?:\/\//, "");
|
|
58591
58696
|
const instructions = [
|
|
58592
58697
|
`Git credentials created (label: "${label}").`,
|
|
@@ -58594,7 +58699,7 @@ async function handleOrgSetupGitCredentials(args) {
|
|
|
58594
58699
|
`Run these commands to configure git:`,
|
|
58595
58700
|
``,
|
|
58596
58701
|
` git config --global credential.helper store`,
|
|
58597
|
-
` echo "https://user:${
|
|
58702
|
+
` echo "https://user:${credentialToken}@${gitHost}" >> ~/.git-credentials`,
|
|
58598
58703
|
``,
|
|
58599
58704
|
`After that, clone a repository with:`,
|
|
58600
58705
|
``,
|
|
@@ -58603,7 +58708,7 @@ async function handleOrgSetupGitCredentials(args) {
|
|
|
58603
58708
|
`The token is shown only once. Store it securely. To revoke it, call org_revoke_git_credentials.`
|
|
58604
58709
|
].join("\n");
|
|
58605
58710
|
return {
|
|
58606
|
-
content: [{ type: "text", text: JSON.stringify({ success: true, data: { token, instructions }, error: null }) }]
|
|
58711
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, data: { token: credentialToken, instructions }, error: null }) }]
|
|
58607
58712
|
};
|
|
58608
58713
|
} catch {
|
|
58609
58714
|
return fail({ code: "UPSTREAM_ERROR", message: "Failed to connect to user service", hint: "The user service is unreachable. Retry shortly." });
|
|
@@ -58615,25 +58720,28 @@ var orgRevokeGitCredentialsTool = {
|
|
|
58615
58720
|
inputSchema: {
|
|
58616
58721
|
type: "object",
|
|
58617
58722
|
properties: {
|
|
58618
|
-
|
|
58723
|
+
token: {
|
|
58619
58724
|
type: "string",
|
|
58620
|
-
description: "
|
|
58725
|
+
description: "JWT session token from org_verify_otp"
|
|
58621
58726
|
},
|
|
58622
|
-
|
|
58727
|
+
credentialId: {
|
|
58623
58728
|
type: "string",
|
|
58624
|
-
description: "ID of the
|
|
58729
|
+
description: "ID of the credential to revoke"
|
|
58625
58730
|
}
|
|
58626
58731
|
},
|
|
58627
|
-
required: ["
|
|
58732
|
+
required: ["token", "credentialId"]
|
|
58628
58733
|
}
|
|
58629
58734
|
};
|
|
58630
58735
|
async function handleOrgRevokeGitCredentials(args) {
|
|
58736
|
+
const sessionToken = args["token"];
|
|
58737
|
+
if (!sessionToken) {
|
|
58738
|
+
return notAuthenticatedResult();
|
|
58739
|
+
}
|
|
58631
58740
|
const credentialId = args["credentialId"];
|
|
58632
|
-
const userId = args["userId"];
|
|
58633
58741
|
try {
|
|
58634
58742
|
const response = await fetch(
|
|
58635
|
-
`${config2.services.userServiceUrl}/git-credentials/${credentialId}
|
|
58636
|
-
{ method: "DELETE" }
|
|
58743
|
+
`${config2.services.userServiceUrl}/git-credentials/${credentialId}`,
|
|
58744
|
+
{ method: "DELETE", headers: authHeaders(sessionToken) }
|
|
58637
58745
|
);
|
|
58638
58746
|
if (!response.ok) {
|
|
58639
58747
|
return fail({ status: response.status, message: "Failed to revoke credential" });
|
|
@@ -58647,23 +58755,27 @@ async function handleOrgRevokeGitCredentials(args) {
|
|
|
58647
58755
|
}
|
|
58648
58756
|
var orgListGitCredentialsTool = {
|
|
58649
58757
|
name: "org_list_git_credentials",
|
|
58650
|
-
description: "List all git credentials for
|
|
58758
|
+
description: "List all git credentials for the authenticated user",
|
|
58651
58759
|
inputSchema: {
|
|
58652
58760
|
type: "object",
|
|
58653
58761
|
properties: {
|
|
58654
|
-
|
|
58762
|
+
token: {
|
|
58655
58763
|
type: "string",
|
|
58656
|
-
description: "
|
|
58764
|
+
description: "JWT session token from org_verify_otp"
|
|
58657
58765
|
}
|
|
58658
58766
|
},
|
|
58659
|
-
required: ["
|
|
58767
|
+
required: ["token"]
|
|
58660
58768
|
}
|
|
58661
58769
|
};
|
|
58662
58770
|
async function handleOrgListGitCredentials(args) {
|
|
58663
|
-
const
|
|
58771
|
+
const sessionToken = args["token"];
|
|
58772
|
+
if (!sessionToken) {
|
|
58773
|
+
return notAuthenticatedResult();
|
|
58774
|
+
}
|
|
58664
58775
|
try {
|
|
58665
58776
|
const response = await fetch(
|
|
58666
|
-
`${config2.services.userServiceUrl}/git-credentials
|
|
58777
|
+
`${config2.services.userServiceUrl}/git-credentials`,
|
|
58778
|
+
{ headers: authHeaders(sessionToken) }
|
|
58667
58779
|
);
|
|
58668
58780
|
if (!response.ok) {
|
|
58669
58781
|
return fail({ status: response.status, message: "Failed to list credentials" });
|
|
@@ -58786,10 +58898,10 @@ var tools9 = [
|
|
|
58786
58898
|
];
|
|
58787
58899
|
|
|
58788
58900
|
// apps/mcp-server/src/tools/refresh-token.ts
|
|
58789
|
-
var
|
|
58901
|
+
var authClient3 = new AuthClient(config2.services.authServiceUrl);
|
|
58790
58902
|
var orgRefreshTokenTool = {
|
|
58791
58903
|
name: "org_refresh_token",
|
|
58792
|
-
description: "Refresh an existing session token
|
|
58904
|
+
description: "Refresh an existing session token, extending its validity for a full new lifetime (7 days by default). Rarely needed: tokens past half of their lifetime are refreshed automatically on any tool call. Use this only to force a refresh explicitly.",
|
|
58793
58905
|
inputSchema: {
|
|
58794
58906
|
type: "object",
|
|
58795
58907
|
properties: {
|
|
@@ -58806,7 +58918,7 @@ async function handleOrgRefreshToken(args) {
|
|
|
58806
58918
|
if (!token) {
|
|
58807
58919
|
return fail({ status: 400, message: "token is required" });
|
|
58808
58920
|
}
|
|
58809
|
-
const result = await
|
|
58921
|
+
const result = await authClient3.refresh({ token });
|
|
58810
58922
|
if (!result) {
|
|
58811
58923
|
return fail({ status: 401, message: "Token refresh failed. Please sign in again with org_request_otp." });
|
|
58812
58924
|
}
|
|
@@ -59406,17 +59518,39 @@ function createServer() {
|
|
|
59406
59518
|
ListToolsRequestSchema,
|
|
59407
59519
|
() => Promise.resolve({ tools: allTools.map((t) => t.definition) })
|
|
59408
59520
|
);
|
|
59409
|
-
server.setRequestHandler(CallToolRequestSchema, (request) => {
|
|
59410
|
-
const { name, arguments:
|
|
59521
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
59522
|
+
const { name, arguments: rawArgs } = request.params;
|
|
59411
59523
|
const handler = toolMap.get(name);
|
|
59412
59524
|
if (!handler) {
|
|
59413
|
-
return
|
|
59525
|
+
return fail({
|
|
59414
59526
|
code: "UNKNOWN_TOOL",
|
|
59415
59527
|
message: `Unknown tool: ${name}`,
|
|
59416
59528
|
hint: "This tool does not exist. List available tools and use one of them."
|
|
59417
|
-
})
|
|
59529
|
+
});
|
|
59530
|
+
}
|
|
59531
|
+
const args = { ...rawArgs ?? {} };
|
|
59532
|
+
let refreshedToken = null;
|
|
59533
|
+
if (name !== "org_refresh_token" && typeof args["token"] === "string") {
|
|
59534
|
+
refreshedToken = await maybeRefreshToken(args["token"]).catch(() => null);
|
|
59535
|
+
if (refreshedToken) {
|
|
59536
|
+
args["token"] = refreshedToken;
|
|
59537
|
+
}
|
|
59418
59538
|
}
|
|
59419
|
-
|
|
59539
|
+
const result = await handler(args).catch(fromCatch);
|
|
59540
|
+
if (refreshedToken) {
|
|
59541
|
+
result.content = [
|
|
59542
|
+
...Array.isArray(result.content) ? result.content : [],
|
|
59543
|
+
{
|
|
59544
|
+
type: "text",
|
|
59545
|
+
text: JSON.stringify({
|
|
59546
|
+
tokenRefreshed: true,
|
|
59547
|
+
token: refreshedToken,
|
|
59548
|
+
note: "Your session token was refreshed automatically. Use this new token for all subsequent tool calls."
|
|
59549
|
+
})
|
|
59550
|
+
}
|
|
59551
|
+
];
|
|
59552
|
+
}
|
|
59553
|
+
return result;
|
|
59420
59554
|
});
|
|
59421
59555
|
return server;
|
|
59422
59556
|
}
|
package/package.json
CHANGED
|
@@ -415,3 +415,31 @@ git push --set-upstream <remote from config> <current branch>
|
|
|
415
415
|
```
|
|
416
416
|
|
|
417
417
|
Tell the user: "✅ Your code is on vibetocloud. Run `/vibetocloud-deploy` to trigger your first deployment."
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Step 7 — Write CLAUDE.md
|
|
422
|
+
|
|
423
|
+
Check whether `CLAUDE.md` exists in the project root using the Read tool.
|
|
424
|
+
|
|
425
|
+
If it exists, read it and check whether it already contains a "VibeToCloud" section. If it does, skip this step.
|
|
426
|
+
|
|
427
|
+
If it does not exist, or exists but has no VibeToCloud section, append the following block (create the file if needed):
|
|
428
|
+
|
|
429
|
+
```markdown
|
|
430
|
+
## VibeToCloud development
|
|
431
|
+
|
|
432
|
+
This project is deployed on VibeToCloud. The `docker-compose.yml` defines how the application runs **in the cloud** — you do not need Docker locally and should never run `docker compose up`.
|
|
433
|
+
|
|
434
|
+
Use the VibeToCloud MCP skills to work with the project:
|
|
435
|
+
- Push code and deploy: `/vibe`
|
|
436
|
+
- Debug running services: `/vibetocloud-debug`
|
|
437
|
+
|
|
438
|
+
All interaction with running containers happens through the MCP tools, not locally.
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
Commit the CLAUDE.md if it was created or changed:
|
|
442
|
+
```bash
|
|
443
|
+
git add CLAUDE.md
|
|
444
|
+
git diff --cached --quiet || git commit -m "chore: add VibeToCloud development instructions to CLAUDE.md"
|
|
445
|
+
```
|