@lovinka/deployik-mcp 0.1.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 (70) hide show
  1. package/README.md +59 -0
  2. package/dist/client/errors.js +51 -0
  3. package/dist/client/errors.js.map +1 -0
  4. package/dist/client/http.js +106 -0
  5. package/dist/client/http.js.map +1 -0
  6. package/dist/client/types.js +5 -0
  7. package/dist/client/types.js.map +1 -0
  8. package/dist/config/audit.js +43 -0
  9. package/dist/config/audit.js.map +1 -0
  10. package/dist/config/binding.js +44 -0
  11. package/dist/config/binding.js.map +1 -0
  12. package/dist/config/cache.js +44 -0
  13. package/dist/config/cache.js.map +1 -0
  14. package/dist/config/env.js +40 -0
  15. package/dist/config/env.js.map +1 -0
  16. package/dist/index.js +22 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/knowledge/index.js +116 -0
  19. package/dist/knowledge/index.js.map +1 -0
  20. package/dist/knowledge/prompts.js +20 -0
  21. package/dist/knowledge/prompts.js.map +1 -0
  22. package/dist/knowledge/recipes.generated.js +17 -0
  23. package/dist/knowledge/recipes.generated.js.map +1 -0
  24. package/dist/lib/format.js +96 -0
  25. package/dist/lib/format.js.map +1 -0
  26. package/dist/lib/logs.js +46 -0
  27. package/dist/lib/logs.js.map +1 -0
  28. package/dist/lib/poll.js +20 -0
  29. package/dist/lib/poll.js.map +1 -0
  30. package/dist/lib/safety.js +38 -0
  31. package/dist/lib/safety.js.map +1 -0
  32. package/dist/resolve/project.js +130 -0
  33. package/dist/resolve/project.js.map +1 -0
  34. package/dist/server.js +32 -0
  35. package/dist/server.js.map +1 -0
  36. package/dist/tools/_helpers.js +76 -0
  37. package/dist/tools/_helpers.js.map +1 -0
  38. package/dist/tools/analytics.js +46 -0
  39. package/dist/tools/analytics.js.map +1 -0
  40. package/dist/tools/auto_build.js +84 -0
  41. package/dist/tools/auto_build.js.map +1 -0
  42. package/dist/tools/deployments.js +120 -0
  43. package/dist/tools/deployments.js.map +1 -0
  44. package/dist/tools/domains.js +104 -0
  45. package/dist/tools/domains.js.map +1 -0
  46. package/dist/tools/email.js +90 -0
  47. package/dist/tools/email.js.map +1 -0
  48. package/dist/tools/env.js +116 -0
  49. package/dist/tools/env.js.map +1 -0
  50. package/dist/tools/github.js +59 -0
  51. package/dist/tools/github.js.map +1 -0
  52. package/dist/tools/help.js +34 -0
  53. package/dist/tools/help.js.map +1 -0
  54. package/dist/tools/index.js +33 -0
  55. package/dist/tools/index.js.map +1 -0
  56. package/dist/tools/projects.js +164 -0
  57. package/dist/tools/projects.js.map +1 -0
  58. package/dist/tools/protection.js +88 -0
  59. package/dist/tools/protection.js.map +1 -0
  60. package/dist/tools/secrets.js +115 -0
  61. package/dist/tools/secrets.js.map +1 -0
  62. package/dist/tools/tokens.js +60 -0
  63. package/dist/tools/tokens.js.map +1 -0
  64. package/dist/tools/volumes.js +77 -0
  65. package/dist/tools/volumes.js.map +1 -0
  66. package/dist/tools/workflows.js +350 -0
  67. package/dist/tools/workflows.js.map +1 -0
  68. package/dist/tools/workspaces.js +48 -0
  69. package/dist/tools/workspaces.js.map +1 -0
  70. package/package.json +50 -0
@@ -0,0 +1,34 @@
1
+ import { z } from "zod";
2
+ import { registerTool } from "./_helpers.js";
3
+ import { getRecipe, listRecipes, RECIPE_TOPICS } from "../knowledge/index.js";
4
+ export function registerHelpTools(server, ctx) {
5
+ registerTool(server, ctx, {
6
+ name: "list_recipes",
7
+ description: "List bundled Deployik how-to recipes available via `get_recipe`. Use these to self-onboard the AI without needing the user to paste docs.",
8
+ annotations: { readOnlyHint: true },
9
+ handler: async () => {
10
+ const recipes = listRecipes();
11
+ const text = recipes.map((r) => ` • ${r.topic.padEnd(22)} ${r.title}\n ${r.summary}`).join("\n");
12
+ return {
13
+ text,
14
+ data: recipes.map((r) => ({ topic: r.topic, title: r.title, summary: r.summary })),
15
+ };
16
+ },
17
+ });
18
+ registerTool(server, ctx, {
19
+ name: "get_recipe",
20
+ description: "Get the full Deployik recipe for a topic. Topics come from the bundled `deployik-howto` skill.",
21
+ inputSchema: {
22
+ topic: z.enum(RECIPE_TOPICS),
23
+ },
24
+ annotations: { readOnlyHint: true },
25
+ handler: async (args) => {
26
+ const recipe = getRecipe(args.topic);
27
+ if (!recipe) {
28
+ return { text: `Unknown topic: ${args.topic}. Call list_recipes for the catalog.`, isError: true };
29
+ }
30
+ return { text: recipe.body, data: { topic: recipe.topic, title: recipe.title } };
31
+ },
32
+ });
33
+ }
34
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/tools/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAoB,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAoB,MAAM,uBAAuB,CAAC;AAEhG,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,GAAgB;IACnE,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE;QACxB,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,2IAA2I;QAC7I,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;QACnC,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxG,OAAO;gBACL,IAAI;gBACJ,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;aACnF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;IAEH,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE;QACxB,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,gGAAgG;QAC7G,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,aAAgD,CAAC;SAChE;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;QACnC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,EAAE,IAAI,EAAE,kBAAkB,IAAI,CAAC,KAAK,sCAAsC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YACrG,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;QACnF,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { registerProjectTools } from "./projects.js";
2
+ import { registerDeploymentTools } from "./deployments.js";
3
+ import { registerEnvTools } from "./env.js";
4
+ import { registerSecretTools } from "./secrets.js";
5
+ import { registerDomainTools } from "./domains.js";
6
+ import { registerAutoBuildTools } from "./auto_build.js";
7
+ import { registerProtectionTools } from "./protection.js";
8
+ import { registerVolumeTools } from "./volumes.js";
9
+ import { registerGithubTools } from "./github.js";
10
+ import { registerWorkspaceTools } from "./workspaces.js";
11
+ import { registerAnalyticsTools } from "./analytics.js";
12
+ import { registerEmailTools } from "./email.js";
13
+ import { registerTokenTools } from "./tokens.js";
14
+ import { registerHelpTools } from "./help.js";
15
+ import { registerWorkflowTools } from "./workflows.js";
16
+ export function registerAllTools(server, ctx) {
17
+ registerProjectTools(server, ctx);
18
+ registerDeploymentTools(server, ctx);
19
+ registerEnvTools(server, ctx);
20
+ registerSecretTools(server, ctx);
21
+ registerDomainTools(server, ctx);
22
+ registerAutoBuildTools(server, ctx);
23
+ registerProtectionTools(server, ctx);
24
+ registerVolumeTools(server, ctx);
25
+ registerGithubTools(server, ctx);
26
+ registerWorkspaceTools(server, ctx);
27
+ registerAnalyticsTools(server, ctx);
28
+ registerEmailTools(server, ctx);
29
+ registerTokenTools(server, ctx);
30
+ registerHelpTools(server, ctx);
31
+ registerWorkflowTools(server, ctx);
32
+ }
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAGvD,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,GAAgB;IAClE,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClC,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,gBAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,164 @@
1
+ import { z } from "zod";
2
+ import { registerTool } from "./_helpers.js";
3
+ import { resolveProject, fetchProjects } from "../resolve/project.js";
4
+ import { checkSafety } from "../lib/safety.js";
5
+ import { renderDryRun, renderProjectSummary } from "../lib/format.js";
6
+ export function registerProjectTools(server, ctx) {
7
+ registerTool(server, ctx, {
8
+ name: "list_projects",
9
+ description: "List Deployik projects this token can access. Optionally filter by workspace.",
10
+ inputSchema: {
11
+ workspace: z.string().optional().describe("Workspace slug or organization id to filter by."),
12
+ },
13
+ annotations: { readOnlyHint: true, title: "List projects" },
14
+ handler: async (args) => {
15
+ const projects = await fetchProjects(ctx);
16
+ const filtered = args.workspace
17
+ ? projects.filter((p) => (p.organization_name ?? "").toLowerCase() === args.workspace.toLowerCase() ||
18
+ p.organization_id === args.workspace)
19
+ : projects;
20
+ const text = filtered.length === 0
21
+ ? "(no projects visible to this token)"
22
+ : filtered
23
+ .map((p) => `• ${p.name} [${p.organization_name ?? p.organization_id}] ${p.github_owner}/${p.github_repo}@${p.branch} status=${p.status}`)
24
+ .join("\n");
25
+ return {
26
+ text,
27
+ data: filtered.map((p) => ({
28
+ id: p.id,
29
+ name: p.name,
30
+ workspace: p.organization_name ?? p.organization_id,
31
+ repo: `${p.github_owner}/${p.github_repo}`,
32
+ branch: p.branch,
33
+ status: p.status,
34
+ })),
35
+ };
36
+ },
37
+ });
38
+ registerTool(server, ctx, {
39
+ name: "get_project",
40
+ description: "Get a single project by id, slug, or the .deployik binding for this repo.",
41
+ inputSchema: {
42
+ project_id: z.string().optional(),
43
+ project: z.string().optional().describe("Project slug, e.g. 'my-app'."),
44
+ workspace: z.string().optional(),
45
+ },
46
+ annotations: { readOnlyHint: true },
47
+ handler: async (args) => {
48
+ const { project } = await resolveProject(ctx, args);
49
+ return { text: renderProjectSummary(project), data: project };
50
+ },
51
+ });
52
+ registerTool(server, ctx, {
53
+ name: "create_project",
54
+ description: "Create a new Deployik project from a GitHub repo. Returns the new project record. Use `setup_project_from_repo` if you want auto-inspection of monorepo apps + an initial deploy.",
55
+ inputSchema: {
56
+ name: z.string().describe("DNS-safe slug. Must match ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$"),
57
+ github_owner: z.string(),
58
+ github_repo: z.string(),
59
+ branch: z.string().default("main"),
60
+ framework: z.enum(["nextjs", "vite", "astro", "static"]).default("nextjs"),
61
+ package_manager: z.enum(["auto", "bun", "pnpm", "npm", "yarn"]).default("auto"),
62
+ root_directory: z.string().default(""),
63
+ output_directory: z.string().default(""),
64
+ build_command: z.string().default(""),
65
+ install_command: z.string().default(""),
66
+ node_version: z.string().default("22"),
67
+ port: z.number().int().min(1).max(65535).default(3000),
68
+ organization_id: z.string().optional(),
69
+ auto_build_enabled: z.boolean().default(true),
70
+ auto_production_enabled: z.boolean().default(false),
71
+ resource_tier: z.enum(["nano", "small", "medium", "large"]).optional(),
72
+ },
73
+ annotations: { title: "Create project" },
74
+ handler: async (args) => {
75
+ const payload = {
76
+ name: args.name,
77
+ github_owner: args.github_owner,
78
+ github_repo: args.github_repo,
79
+ branch: args.branch,
80
+ framework: args.framework,
81
+ package_manager: args.package_manager,
82
+ root_directory: args.root_directory,
83
+ output_directory: args.output_directory,
84
+ build_command: args.build_command,
85
+ install_command: args.install_command,
86
+ node_version: args.node_version,
87
+ port: args.port,
88
+ auto_build_enabled: args.auto_build_enabled,
89
+ auto_production_enabled: args.auto_production_enabled,
90
+ };
91
+ if (args.organization_id)
92
+ payload.organization_id = args.organization_id;
93
+ if (args.resource_tier)
94
+ payload.resource_tier = args.resource_tier;
95
+ const project = await ctx.client.request(`/projects`, { method: "POST", body: payload });
96
+ return { text: `Created project '${project.name}' (id: ${project.id}).\n\n${renderProjectSummary(project)}`, data: project };
97
+ },
98
+ });
99
+ registerTool(server, ctx, {
100
+ name: "update_project",
101
+ description: "Patch fields on a project. Pass any subset of mutable fields.",
102
+ inputSchema: {
103
+ project_id: z.string().optional(),
104
+ project: z.string().optional(),
105
+ patch: z
106
+ .object({
107
+ name: z.string().optional(),
108
+ branch: z.string().optional(),
109
+ framework: z.string().optional(),
110
+ package_manager: z.string().optional(),
111
+ root_directory: z.string().optional(),
112
+ output_directory: z.string().optional(),
113
+ build_command: z.string().optional(),
114
+ install_command: z.string().optional(),
115
+ node_version: z.string().optional(),
116
+ port: z.number().optional(),
117
+ host_network_access: z.boolean().optional(),
118
+ data_volume_enabled: z.boolean().optional(),
119
+ data_mount_path: z.string().optional(),
120
+ resource_tier: z.enum(["nano", "small", "medium", "large"]).optional(),
121
+ })
122
+ .describe("Fields to update. Server validates."),
123
+ },
124
+ handler: async (args) => {
125
+ const { project } = await resolveProject(ctx, args);
126
+ const updated = await ctx.client.request(`/projects/${project.id}`, {
127
+ method: "PATCH",
128
+ body: args.patch,
129
+ });
130
+ return { text: renderProjectSummary(updated), data: updated };
131
+ },
132
+ });
133
+ registerTool(server, ctx, {
134
+ name: "delete_project",
135
+ description: "Soft-delete a project (stops containers, removes nginx configs, cleans domains). Destructive — requires `confirm: true` AND `confirm_name: <project slug>`.",
136
+ inputSchema: {
137
+ project_id: z.string().optional(),
138
+ project: z.string().optional(),
139
+ confirm: z.boolean().optional(),
140
+ confirm_name: z.string().optional(),
141
+ },
142
+ annotations: { destructiveHint: true },
143
+ audit: true,
144
+ handler: async (args) => {
145
+ const { project } = await resolveProject(ctx, args);
146
+ const safety = checkSafety({
147
+ toolName: "delete_project",
148
+ tier: "destructive_production",
149
+ expectedName: project.name,
150
+ impact: {
151
+ project: project.name,
152
+ id: project.id,
153
+ workspace: project.organization_name ?? project.organization_id,
154
+ note: "Will stop all containers, remove nginx configs, drop domains. Soft-deleted in DB (status='deleted').",
155
+ },
156
+ }, { confirm: args.confirm, confirm_name: args.confirm_name });
157
+ if (!safety.proceed)
158
+ return { text: renderDryRun(safety.dryRun) };
159
+ await ctx.client.request(`/projects/${project.id}`, { method: "DELETE" });
160
+ return { text: `Deleted project '${project.name}' (id: ${project.id}).` };
161
+ },
162
+ });
163
+ }
164
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/tools/projects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ import { z } from "zod";
2
+ import { registerTool } from "./_helpers.js";
3
+ import { resolveProject } from "../resolve/project.js";
4
+ import { checkSafety } from "../lib/safety.js";
5
+ import { renderDryRun, renderProtection } from "../lib/format.js";
6
+ const ENV = z.enum(["preview", "production"]);
7
+ export function registerProtectionTools(server, ctx) {
8
+ registerTool(server, ctx, {
9
+ name: "get_protection",
10
+ description: "Check whether password protection is enabled on preview and/or production.",
11
+ inputSchema: {
12
+ project_id: z.string().optional(),
13
+ project: z.string().optional(),
14
+ },
15
+ annotations: { readOnlyHint: true },
16
+ handler: async (args) => {
17
+ const { project } = await resolveProject(ctx, args);
18
+ const status = await ctx.client.request(`/projects/${project.id}/protection`);
19
+ return { text: `Protection on ${project.name}:\n${renderProtection(status)}`, data: status };
20
+ },
21
+ });
22
+ registerTool(server, ctx, {
23
+ name: "set_protection",
24
+ description: "Enable or disable password protection for one environment. When enabling, returns the generated password (shown ONCE — store it).",
25
+ inputSchema: {
26
+ project_id: z.string().optional(),
27
+ project: z.string().optional(),
28
+ environment: ENV,
29
+ enabled: z.boolean(),
30
+ confirm: z.boolean().optional(),
31
+ confirm_name: z.string().optional(),
32
+ },
33
+ annotations: { destructiveHint: true },
34
+ audit: true,
35
+ handler: async (args) => {
36
+ const { project } = await resolveProject(ctx, args);
37
+ // Disabling protection is destructive (exposes site); production gets the higher tier.
38
+ const tier = args.environment === "production" ? "destructive_production" : args.enabled ? "mutating" : "destructive";
39
+ if (tier !== "mutating") {
40
+ const safety = checkSafety({
41
+ toolName: "set_protection",
42
+ tier,
43
+ expectedName: project.name,
44
+ impact: { project: project.name, environment: args.environment, enabled: args.enabled },
45
+ }, { confirm: args.confirm, confirm_name: args.confirm_name });
46
+ if (!safety.proceed)
47
+ return { text: renderDryRun(safety.dryRun) };
48
+ }
49
+ const res = await ctx.client.request(`/projects/${project.id}/protection`, {
50
+ method: "PUT",
51
+ body: { environment: args.environment, enabled: args.enabled },
52
+ });
53
+ const passwordLine = res.password ? `\nPassword (shown once): ${res.password}` : "";
54
+ return { text: `Protection ${res.enabled ? "enabled" : "disabled"} on ${args.environment} of ${project.name}.${passwordLine}`, data: res };
55
+ },
56
+ });
57
+ registerTool(server, ctx, {
58
+ name: "regenerate_protection_password",
59
+ description: "Generate a fresh password for an already-protected environment. Old password stays valid only for existing cookies (24h TTL).",
60
+ inputSchema: {
61
+ project_id: z.string().optional(),
62
+ project: z.string().optional(),
63
+ environment: ENV,
64
+ confirm: z.boolean().optional(),
65
+ confirm_name: z.string().optional(),
66
+ },
67
+ annotations: { destructiveHint: true },
68
+ audit: true,
69
+ handler: async (args) => {
70
+ const { project } = await resolveProject(ctx, args);
71
+ const tier = args.environment === "production" ? "destructive_production" : "destructive";
72
+ const safety = checkSafety({
73
+ toolName: "regenerate_protection_password",
74
+ tier,
75
+ expectedName: project.name,
76
+ impact: { project: project.name, environment: args.environment, note: "Old password keeps working only for already-issued cookies." },
77
+ }, { confirm: args.confirm, confirm_name: args.confirm_name });
78
+ if (!safety.proceed)
79
+ return { text: renderDryRun(safety.dryRun) };
80
+ const res = await ctx.client.request(`/projects/${project.id}/protection/regenerate`, {
81
+ method: "POST",
82
+ body: { environment: args.environment },
83
+ });
84
+ return { text: `New password for ${args.environment} of ${project.name} (shown once):\n${res.password ?? "(none returned)"}`, data: res };
85
+ },
86
+ });
87
+ }
88
+ //# sourceMappingURL=protection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protection.js","sourceRoot":"","sources":["../../src/tools/protection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,115 @@
1
+ import { z } from "zod";
2
+ import { registerTool } from "./_helpers.js";
3
+ import { resolveProject } from "../resolve/project.js";
4
+ import { checkSafety } from "../lib/safety.js";
5
+ import { renderDryRun } from "../lib/format.js";
6
+ const SCOPE = z.enum(["shared", "preview", "production"]);
7
+ export function registerSecretTools(server, ctx) {
8
+ registerTool(server, ctx, {
9
+ name: "list_secrets",
10
+ description: "List secrets for a project + scope. Values are masked.",
11
+ inputSchema: {
12
+ project_id: z.string().optional(),
13
+ project: z.string().optional(),
14
+ environment: SCOPE,
15
+ },
16
+ annotations: { readOnlyHint: true },
17
+ handler: async (args) => {
18
+ const { project } = await resolveProject(ctx, args);
19
+ const vars = await ctx.client.request(`/projects/${project.id}/secrets`, {
20
+ query: { environment: args.environment },
21
+ });
22
+ const text = vars.length === 0
23
+ ? "(no secrets in this scope)"
24
+ : vars.map((v) => ` ${v.key} = ${v.value}`).join("\n");
25
+ return { text, data: vars };
26
+ },
27
+ });
28
+ registerTool(server, ctx, {
29
+ name: "upsert_secret",
30
+ description: "Set (create or update) a single secret. Use this for additive changes. `NEXT_PUBLIC_*` keys are rejected by the backend (use env vars instead).",
31
+ inputSchema: {
32
+ project_id: z.string().optional(),
33
+ project: z.string().optional(),
34
+ environment: SCOPE,
35
+ key: z.string(),
36
+ value: z.string(),
37
+ },
38
+ handler: async (args) => {
39
+ const { project } = await resolveProject(ctx, args);
40
+ await ctx.client.request(`/projects/${project.id}/secrets`, {
41
+ method: "POST",
42
+ body: { environment: args.environment, key: args.key, value: args.value },
43
+ });
44
+ return { text: `Set secret ${args.key} in ${args.environment} scope of ${project.name}.` };
45
+ },
46
+ });
47
+ registerTool(server, ctx, {
48
+ name: "bulk_set_secrets",
49
+ description: "REPLACE all secrets in a scope. Destructive — requires `confirm: true` (and `confirm_name` for production).",
50
+ inputSchema: {
51
+ project_id: z.string().optional(),
52
+ project: z.string().optional(),
53
+ environment: SCOPE,
54
+ variables: z.array(z.object({ key: z.string(), value: z.string() })).min(0),
55
+ confirm: z.boolean().optional(),
56
+ confirm_name: z.string().optional(),
57
+ },
58
+ annotations: { destructiveHint: true },
59
+ audit: true,
60
+ handler: async (args) => {
61
+ const { project } = await resolveProject(ctx, args);
62
+ const tier = args.environment === "production" ? "destructive_production" : "destructive";
63
+ const safety = checkSafety({
64
+ toolName: "bulk_set_secrets",
65
+ tier,
66
+ expectedName: project.name,
67
+ impact: {
68
+ project: project.name,
69
+ scope: args.environment,
70
+ replacing_with: args.variables.length,
71
+ note: "Existing secrets not in this set will be DELETED.",
72
+ },
73
+ }, { confirm: args.confirm, confirm_name: args.confirm_name });
74
+ if (!safety.proceed)
75
+ return { text: renderDryRun(safety.dryRun) };
76
+ const res = await ctx.client.request(`/projects/${project.id}/secrets`, {
77
+ method: "PUT",
78
+ body: { environment: args.environment, variables: args.variables },
79
+ });
80
+ return { text: `Replaced ${args.environment} secrets on ${project.name} — now ${res.count} keys.` };
81
+ },
82
+ });
83
+ registerTool(server, ctx, {
84
+ name: "delete_secret",
85
+ description: "Delete a secret. Requires `confirm: true` (and `confirm_name` for production).",
86
+ inputSchema: {
87
+ project_id: z.string().optional(),
88
+ project: z.string().optional(),
89
+ environment: SCOPE,
90
+ key: z.string(),
91
+ confirm: z.boolean().optional(),
92
+ confirm_name: z.string().optional(),
93
+ },
94
+ annotations: { destructiveHint: true },
95
+ audit: true,
96
+ handler: async (args) => {
97
+ const { project } = await resolveProject(ctx, args);
98
+ const tier = args.environment === "production" ? "destructive_production" : "destructive";
99
+ const safety = checkSafety({
100
+ toolName: "delete_secret",
101
+ tier,
102
+ expectedName: project.name,
103
+ impact: { project: project.name, scope: args.environment, key: args.key },
104
+ }, { confirm: args.confirm, confirm_name: args.confirm_name });
105
+ if (!safety.proceed)
106
+ return { text: renderDryRun(safety.dryRun) };
107
+ await ctx.client.request(`/projects/${project.id}/secrets/${encodeURIComponent(args.key)}`, {
108
+ method: "DELETE",
109
+ query: { environment: args.environment },
110
+ });
111
+ return { text: `Deleted secret ${args.key} from ${args.environment} scope of ${project.name}.` };
112
+ },
113
+ });
114
+ }
115
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/tools/secrets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { z } from "zod";
2
+ import { registerTool } from "./_helpers.js";
3
+ import { checkSafety } from "../lib/safety.js";
4
+ import { renderDryRun } from "../lib/format.js";
5
+ export function registerTokenTools(server, ctx) {
6
+ registerTool(server, ctx, {
7
+ name: "list_my_tokens",
8
+ description: "List Personal Access Tokens belonging to the token owner. Raw values are never returned.",
9
+ annotations: { readOnlyHint: true },
10
+ handler: async () => {
11
+ const tokens = await ctx.client.request(`/me/tokens`);
12
+ const text = tokens
13
+ .map((t) => {
14
+ const status = t.revoked_at ? "revoked" : t.expires_at && Date.parse(t.expires_at) < Date.now() ? "expired" : "active";
15
+ return ` • ${t.name.padEnd(32)} ${status.padEnd(8)} last_used=${t.last_used_at ?? "(never)"} id=${t.id}`;
16
+ })
17
+ .join("\n");
18
+ return { text: text || "(no tokens)", data: tokens };
19
+ },
20
+ });
21
+ registerTool(server, ctx, {
22
+ name: "create_my_token",
23
+ description: "Create a new Personal Access Token. The raw token value is returned ONCE — store it immediately, the server only keeps a hash.",
24
+ inputSchema: {
25
+ name: z.string().max(100),
26
+ },
27
+ handler: async (args) => {
28
+ const res = await ctx.client.request(`/me/tokens`, {
29
+ method: "POST",
30
+ body: { name: args.name },
31
+ });
32
+ return {
33
+ text: `Created token '${res.name}' (id: ${res.id}).\n\nRaw token (copy now, will not be shown again):\n${res.token}`,
34
+ data: res,
35
+ };
36
+ },
37
+ });
38
+ registerTool(server, ctx, {
39
+ name: "revoke_my_token",
40
+ description: "Revoke a Personal Access Token. Requires `confirm: true`.",
41
+ inputSchema: {
42
+ id: z.string(),
43
+ confirm: z.boolean().optional(),
44
+ },
45
+ annotations: { destructiveHint: true },
46
+ audit: true,
47
+ handler: async (args) => {
48
+ const safety = checkSafety({
49
+ toolName: "revoke_my_token",
50
+ tier: "destructive",
51
+ impact: { token_id: args.id, note: "Token can no longer authenticate." },
52
+ }, { confirm: args.confirm });
53
+ if (!safety.proceed)
54
+ return { text: renderDryRun(safety.dryRun) };
55
+ await ctx.client.request(`/me/tokens/${args.id}`, { method: "DELETE" });
56
+ return { text: `Revoked token ${args.id}.` };
57
+ },
58
+ });
59
+ }
60
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/tools/tokens.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import { z } from "zod";
2
+ import { registerTool } from "./_helpers.js";
3
+ import { resolveProject } from "../resolve/project.js";
4
+ import { checkSafety } from "../lib/safety.js";
5
+ import { renderDryRun, renderVolumesList } from "../lib/format.js";
6
+ const ENV = z.enum(["preview", "production"]);
7
+ export function registerVolumeTools(server, ctx) {
8
+ registerTool(server, ctx, {
9
+ name: "list_volumes",
10
+ description: "List preview + production volumes for a project with on-disk size and in_use flag.",
11
+ inputSchema: {
12
+ project_id: z.string().optional(),
13
+ project: z.string().optional(),
14
+ },
15
+ annotations: { readOnlyHint: true },
16
+ handler: async (args) => {
17
+ const { project } = await resolveProject(ctx, args);
18
+ const volumes = await ctx.client.request(`/projects/${project.id}/volumes`);
19
+ return { text: renderVolumesList(volumes), data: volumes };
20
+ },
21
+ });
22
+ registerTool(server, ctx, {
23
+ name: "delete_volume",
24
+ description: "Delete a named volume for one environment. The volume must not be in use (returns 409 otherwise). Requires `confirm: true`.",
25
+ inputSchema: {
26
+ project_id: z.string().optional(),
27
+ project: z.string().optional(),
28
+ environment: ENV,
29
+ confirm: z.boolean().optional(),
30
+ confirm_name: z.string().optional(),
31
+ },
32
+ annotations: { destructiveHint: true },
33
+ audit: true,
34
+ handler: async (args) => {
35
+ const { project } = await resolveProject(ctx, args);
36
+ const tier = args.environment === "production" ? "destructive_production" : "destructive";
37
+ const safety = checkSafety({
38
+ toolName: "delete_volume",
39
+ tier,
40
+ expectedName: project.name,
41
+ impact: { project: project.name, environment: args.environment, note: "All data on this volume is lost." },
42
+ }, { confirm: args.confirm, confirm_name: args.confirm_name });
43
+ if (!safety.proceed)
44
+ return { text: renderDryRun(safety.dryRun) };
45
+ await ctx.client.request(`/projects/${project.id}/volumes/${args.environment}`, { method: "DELETE" });
46
+ return { text: `Deleted ${args.environment} volume for ${project.name}.` };
47
+ },
48
+ });
49
+ registerTool(server, ctx, {
50
+ name: "recreate_volume",
51
+ description: "Drop and recreate a volume. Container must be stopped (returns 409 otherwise). Requires `confirm: true`.",
52
+ inputSchema: {
53
+ project_id: z.string().optional(),
54
+ project: z.string().optional(),
55
+ environment: ENV,
56
+ confirm: z.boolean().optional(),
57
+ confirm_name: z.string().optional(),
58
+ },
59
+ annotations: { destructiveHint: true },
60
+ audit: true,
61
+ handler: async (args) => {
62
+ const { project } = await resolveProject(ctx, args);
63
+ const tier = args.environment === "production" ? "destructive_production" : "destructive";
64
+ const safety = checkSafety({
65
+ toolName: "recreate_volume",
66
+ tier,
67
+ expectedName: project.name,
68
+ impact: { project: project.name, environment: args.environment, note: "Drops all data on the volume and creates a fresh empty one." },
69
+ }, { confirm: args.confirm, confirm_name: args.confirm_name });
70
+ if (!safety.proceed)
71
+ return { text: renderDryRun(safety.dryRun) };
72
+ await ctx.client.request(`/projects/${project.id}/volumes/${args.environment}/recreate`, { method: "POST" });
73
+ return { text: `Recreated ${args.environment} volume for ${project.name}.` };
74
+ },
75
+ });
76
+ }
77
+ //# sourceMappingURL=volumes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"volumes.js","sourceRoot":"","sources":["../../src/tools/volumes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAoB,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGnE,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC;AAE9C,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,GAAgB;IACrE,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE;QACxB,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,oFAAoF;QACjG,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACjC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SAC/B;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;QACnC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACpD,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAe,aAAa,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC;YAC1F,OAAO,EAAE,IAAI,EAAE,iBAAiB,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC7D,CAAC;KACF,CAAC,CAAC;IAEH,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE;QACxB,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,6HAA6H;QAC1I,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACjC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC9B,WAAW,EAAE,GAAG;YAChB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YAC/B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SACpC;QACD,WAAW,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;QACtC,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,KAAK,YAAY,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,aAAa,CAAC;YAC1F,MAAM,MAAM,GAAG,WAAW,CACxB;gBACE,QAAQ,EAAE,eAAe;gBACzB,IAAI;gBACJ,YAAY,EAAE,OAAO,CAAC,IAAI;gBAC1B,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,kCAAkC,EAAE;aAC3G,EACD,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAC3D,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,OAAO;gBAAE,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAClE,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,OAAO,CAAC,EAAE,YAAY,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;YACtG,OAAO,EAAE,IAAI,EAAE,WAAW,IAAI,CAAC,WAAW,eAAe,OAAO,CAAC,IAAI,GAAG,EAAE,CAAC;QAC7E,CAAC;KACF,CAAC,CAAC;IAEH,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE;QACxB,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,0GAA0G;QACvH,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACjC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC9B,WAAW,EAAE,GAAG;YAChB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YAC/B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SACpC;QACD,WAAW,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;QACtC,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,KAAK,YAAY,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,aAAa,CAAC;YAC1F,MAAM,MAAM,GAAG,WAAW,CACxB;gBACE,QAAQ,EAAE,iBAAiB;gBAC3B,IAAI;gBACJ,YAAY,EAAE,OAAO,CAAC,IAAI;gBAC1B,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,6DAA6D,EAAE;aACtI,EACD,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAC3D,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,OAAO;gBAAE,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAClE,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,OAAO,CAAC,EAAE,YAAY,IAAI,CAAC,WAAW,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAC7G,OAAO,EAAE,IAAI,EAAE,aAAa,IAAI,CAAC,WAAW,eAAe,OAAO,CAAC,IAAI,GAAG,EAAE,CAAC;QAC/E,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}