@octopusdeploy/mcp-server 1.0.1 → 2.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 (290) hide show
  1. package/README.md +237 -46
  2. package/dist/helpers/activeToolsetConfig.d.ts +4 -0
  3. package/dist/helpers/activeToolsetConfig.d.ts.map +1 -0
  4. package/dist/helpers/activeToolsetConfig.js +18 -0
  5. package/dist/helpers/activeToolsetConfig.js.map +1 -0
  6. package/dist/helpers/errorHandling.d.ts +38 -0
  7. package/dist/helpers/errorHandling.d.ts.map +1 -0
  8. package/dist/helpers/errorHandling.js +75 -0
  9. package/dist/helpers/errorHandling.js.map +1 -0
  10. package/dist/helpers/getClientConfigurationFromEnvironment.d.ts +2 -0
  11. package/dist/helpers/getClientConfigurationFromEnvironment.d.ts.map +1 -1
  12. package/dist/helpers/getClientConfigurationFromEnvironment.js +21 -5
  13. package/dist/helpers/getClientConfigurationFromEnvironment.js.map +1 -1
  14. package/dist/helpers/grepLines.d.ts +38 -0
  15. package/dist/helpers/grepLines.d.ts.map +1 -0
  16. package/dist/helpers/grepLines.js +65 -0
  17. package/dist/helpers/grepLines.js.map +1 -0
  18. package/dist/helpers/methodTier.d.ts +15 -0
  19. package/dist/helpers/methodTier.d.ts.map +1 -0
  20. package/dist/helpers/methodTier.js +25 -0
  21. package/dist/helpers/methodTier.js.map +1 -0
  22. package/dist/helpers/pathAllowlist.d.ts +27 -0
  23. package/dist/helpers/pathAllowlist.d.ts.map +1 -0
  24. package/dist/helpers/pathAllowlist.js +177 -0
  25. package/dist/helpers/pathAllowlist.js.map +1 -0
  26. package/dist/helpers/pathGlob.d.ts +15 -0
  27. package/dist/helpers/pathGlob.d.ts.map +1 -0
  28. package/dist/helpers/pathGlob.js +47 -0
  29. package/dist/helpers/pathGlob.js.map +1 -0
  30. package/dist/helpers/requireConfirmation.d.ts +119 -0
  31. package/dist/helpers/requireConfirmation.d.ts.map +1 -0
  32. package/dist/helpers/requireConfirmation.js +148 -0
  33. package/dist/helpers/requireConfirmation.js.map +1 -0
  34. package/dist/helpers/sensitivePathDenylist.d.ts +32 -0
  35. package/dist/helpers/sensitivePathDenylist.d.ts.map +1 -0
  36. package/dist/helpers/sensitivePathDenylist.js +49 -0
  37. package/dist/helpers/sensitivePathDenylist.js.map +1 -0
  38. package/dist/helpers/spaceResolver.d.ts +4 -0
  39. package/dist/helpers/spaceResolver.d.ts.map +1 -0
  40. package/dist/helpers/spaceResolver.js +18 -0
  41. package/dist/helpers/spaceResolver.js.map +1 -0
  42. package/dist/helpers/stripLinks.d.ts +15 -0
  43. package/dist/helpers/stripLinks.d.ts.map +1 -0
  44. package/dist/helpers/stripLinks.js +19 -0
  45. package/dist/helpers/stripLinks.js.map +1 -0
  46. package/dist/helpers/urlParser.d.ts +16 -0
  47. package/dist/helpers/urlParser.d.ts.map +1 -0
  48. package/dist/helpers/urlParser.js +83 -0
  49. package/dist/helpers/urlParser.js.map +1 -0
  50. package/dist/helpers/userCache.d.ts +14 -0
  51. package/dist/helpers/userCache.d.ts.map +1 -0
  52. package/dist/helpers/userCache.js +16 -0
  53. package/dist/helpers/userCache.js.map +1 -0
  54. package/dist/helpers/validateExecutePath.d.ts +29 -0
  55. package/dist/helpers/validateExecutePath.d.ts.map +1 -0
  56. package/dist/helpers/validateExecutePath.js +62 -0
  57. package/dist/helpers/validateExecutePath.js.map +1 -0
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +64 -15
  60. package/dist/index.js.map +1 -1
  61. package/dist/resources/catalog/capabilities.d.ts +36 -0
  62. package/dist/resources/catalog/capabilities.d.ts.map +1 -0
  63. package/dist/resources/catalog/capabilities.js +90 -0
  64. package/dist/resources/catalog/capabilities.js.map +1 -0
  65. package/dist/resources/catalog/llmsTxt.d.ts +8 -0
  66. package/dist/resources/catalog/llmsTxt.d.ts.map +1 -0
  67. package/dist/resources/catalog/llmsTxt.js +44 -0
  68. package/dist/resources/catalog/llmsTxt.js.map +1 -0
  69. package/dist/resources/dispatch.d.ts +30 -0
  70. package/dist/resources/dispatch.d.ts.map +1 -0
  71. package/dist/resources/dispatch.js +81 -0
  72. package/dist/resources/dispatch.js.map +1 -0
  73. package/dist/resources/featureToggle.d.ts +2 -0
  74. package/dist/resources/featureToggle.d.ts.map +1 -0
  75. package/dist/resources/featureToggle.js +34 -0
  76. package/dist/resources/featureToggle.js.map +1 -0
  77. package/dist/resources/index.d.ts +12 -0
  78. package/dist/resources/index.d.ts.map +1 -0
  79. package/dist/resources/index.js +44 -0
  80. package/dist/resources/index.js.map +1 -0
  81. package/dist/resources/interruption.d.ts +2 -0
  82. package/dist/resources/interruption.d.ts.map +1 -0
  83. package/dist/resources/interruption.js +34 -0
  84. package/dist/resources/interruption.js.map +1 -0
  85. package/dist/resources/release.d.ts +2 -0
  86. package/dist/resources/release.d.ts.map +1 -0
  87. package/dist/resources/release.js +33 -0
  88. package/dist/resources/release.js.map +1 -0
  89. package/dist/resources/rolloutGroup.d.ts +2 -0
  90. package/dist/resources/rolloutGroup.d.ts.map +1 -0
  91. package/dist/resources/rolloutGroup.js +35 -0
  92. package/dist/resources/rolloutGroup.js.map +1 -0
  93. package/dist/resources/runbook.d.ts +2 -0
  94. package/dist/resources/runbook.d.ts.map +1 -0
  95. package/dist/resources/runbook.js +34 -0
  96. package/dist/resources/runbook.js.map +1 -0
  97. package/dist/resources/task.d.ts +2 -0
  98. package/dist/resources/task.d.ts.map +1 -0
  99. package/dist/resources/task.js +68 -0
  100. package/dist/resources/task.js.map +1 -0
  101. package/dist/tools/createRelease.d.ts +3 -0
  102. package/dist/tools/createRelease.d.ts.map +1 -0
  103. package/dist/tools/createRelease.js +151 -0
  104. package/dist/tools/createRelease.js.map +1 -0
  105. package/dist/tools/deployRelease.d.ts +3 -0
  106. package/dist/tools/deployRelease.d.ts.map +1 -0
  107. package/dist/tools/deployRelease.js +227 -0
  108. package/dist/tools/deployRelease.js.map +1 -0
  109. package/dist/tools/execute.d.ts +3 -0
  110. package/dist/tools/execute.d.ts.map +1 -0
  111. package/dist/tools/execute.js +261 -0
  112. package/dist/tools/execute.js.map +1 -0
  113. package/dist/tools/findAccounts.d.ts +3 -0
  114. package/dist/tools/findAccounts.d.ts.map +1 -0
  115. package/dist/tools/findAccounts.js +90 -0
  116. package/dist/tools/findAccounts.js.map +1 -0
  117. package/dist/tools/findCertificates.d.ts +3 -0
  118. package/dist/tools/findCertificates.d.ts.map +1 -0
  119. package/dist/tools/findCertificates.js +98 -0
  120. package/dist/tools/findCertificates.js.map +1 -0
  121. package/dist/tools/findDeploymentTargets.d.ts +3 -0
  122. package/dist/tools/findDeploymentTargets.d.ts.map +1 -0
  123. package/dist/tools/findDeploymentTargets.js +161 -0
  124. package/dist/tools/findDeploymentTargets.js.map +1 -0
  125. package/dist/tools/findFeatureToggles.d.ts +37 -0
  126. package/dist/tools/findFeatureToggles.d.ts.map +1 -0
  127. package/dist/tools/findFeatureToggles.js +139 -0
  128. package/dist/tools/findFeatureToggles.js.map +1 -0
  129. package/dist/tools/findInterruptions.d.ts +79 -0
  130. package/dist/tools/findInterruptions.d.ts.map +1 -0
  131. package/dist/tools/findInterruptions.js +273 -0
  132. package/dist/tools/findInterruptions.js.map +1 -0
  133. package/dist/tools/findReleases.d.ts +3 -0
  134. package/dist/tools/findReleases.d.ts.map +1 -0
  135. package/dist/tools/findReleases.js +138 -0
  136. package/dist/tools/findReleases.js.map +1 -0
  137. package/dist/tools/findRunbooks.d.ts +3 -0
  138. package/dist/tools/findRunbooks.d.ts.map +1 -0
  139. package/dist/tools/findRunbooks.js +139 -0
  140. package/dist/tools/findRunbooks.js.map +1 -0
  141. package/dist/tools/findTenants.d.ts +19 -0
  142. package/dist/tools/findTenants.d.ts.map +1 -0
  143. package/dist/tools/findTenants.js +133 -0
  144. package/dist/tools/findTenants.js.map +1 -0
  145. package/dist/tools/getBranches.d.ts.map +1 -1
  146. package/dist/tools/getBranches.js +51 -33
  147. package/dist/tools/getBranches.js.map +1 -1
  148. package/dist/tools/getCurrentUser.d.ts.map +1 -1
  149. package/dist/tools/getCurrentUser.js +34 -25
  150. package/dist/tools/getCurrentUser.js.map +1 -1
  151. package/dist/tools/getDeploymentFromUrl.d.ts +57 -0
  152. package/dist/tools/getDeploymentFromUrl.d.ts.map +1 -0
  153. package/dist/tools/getDeploymentFromUrl.js +162 -0
  154. package/dist/tools/getDeploymentFromUrl.js.map +1 -0
  155. package/dist/tools/getDeploymentProcess.d.ts.map +1 -1
  156. package/dist/tools/getDeploymentProcess.js +57 -19
  157. package/dist/tools/getDeploymentProcess.js.map +1 -1
  158. package/dist/tools/getKubernetesLiveStatus.d.ts.map +1 -1
  159. package/dist/tools/getKubernetesLiveStatus.js +70 -48
  160. package/dist/tools/getKubernetesLiveStatus.js.map +1 -1
  161. package/dist/tools/getMissingTenantVariables.d.ts.map +1 -1
  162. package/dist/tools/getMissingTenantVariables.js +58 -26
  163. package/dist/tools/getMissingTenantVariables.js.map +1 -1
  164. package/dist/tools/getTaskFromUrl.d.ts +18 -0
  165. package/dist/tools/getTaskFromUrl.d.ts.map +1 -0
  166. package/dist/tools/getTaskFromUrl.js +90 -0
  167. package/dist/tools/getTaskFromUrl.js.map +1 -0
  168. package/dist/tools/getTenantVariables.d.ts.map +1 -1
  169. package/dist/tools/getTenantVariables.js +58 -38
  170. package/dist/tools/getTenantVariables.js.map +1 -1
  171. package/dist/tools/getVariables.d.ts.map +1 -1
  172. package/dist/tools/getVariables.js +12 -9
  173. package/dist/tools/getVariables.js.map +1 -1
  174. package/dist/tools/grepLlmsTxt.d.ts +13 -0
  175. package/dist/tools/grepLlmsTxt.d.ts.map +1 -0
  176. package/dist/tools/grepLlmsTxt.js +105 -0
  177. package/dist/tools/grepLlmsTxt.js.map +1 -0
  178. package/dist/tools/grepTaskLog.d.ts +30 -0
  179. package/dist/tools/grepTaskLog.d.ts.map +1 -0
  180. package/dist/tools/grepTaskLog.js +116 -0
  181. package/dist/tools/grepTaskLog.js.map +1 -0
  182. package/dist/tools/index.d.ts +22 -18
  183. package/dist/tools/index.d.ts.map +1 -1
  184. package/dist/tools/index.js +33 -21
  185. package/dist/tools/index.js.map +1 -1
  186. package/dist/tools/listDeployments.d.ts.map +1 -1
  187. package/dist/tools/listDeployments.js +77 -37
  188. package/dist/tools/listDeployments.js.map +1 -1
  189. package/dist/tools/listEnvironments.d.ts.map +1 -1
  190. package/dist/tools/listEnvironments.js +63 -37
  191. package/dist/tools/listEnvironments.js.map +1 -1
  192. package/dist/tools/listProjects.d.ts.map +1 -1
  193. package/dist/tools/listProjects.js +64 -38
  194. package/dist/tools/listProjects.js.map +1 -1
  195. package/dist/tools/listSpaces.d.ts.map +1 -1
  196. package/dist/tools/listSpaces.js +56 -30
  197. package/dist/tools/listSpaces.js.map +1 -1
  198. package/dist/tools/readResource.d.ts +3 -0
  199. package/dist/tools/readResource.d.ts.map +1 -0
  200. package/dist/tools/readResource.js +50 -0
  201. package/dist/tools/readResource.js.map +1 -0
  202. package/dist/tools/runRunbook.d.ts +3 -0
  203. package/dist/tools/runRunbook.d.ts.map +1 -0
  204. package/dist/tools/runRunbook.js +174 -0
  205. package/dist/tools/runRunbook.js.map +1 -0
  206. package/dist/tools/updateFeatureToggle.d.ts +94 -0
  207. package/dist/tools/updateFeatureToggle.d.ts.map +1 -0
  208. package/dist/tools/updateFeatureToggle.js +308 -0
  209. package/dist/tools/updateFeatureToggle.js.map +1 -0
  210. package/dist/types/featureToggleTypes.d.ts +47 -0
  211. package/dist/types/featureToggleTypes.d.ts.map +1 -0
  212. package/dist/types/featureToggleTypes.js +10 -0
  213. package/dist/types/featureToggleTypes.js.map +1 -0
  214. package/dist/types/resourceConfig.d.ts +17 -0
  215. package/dist/types/resourceConfig.d.ts.map +1 -0
  216. package/dist/types/resourceConfig.js +6 -0
  217. package/dist/types/resourceConfig.js.map +1 -0
  218. package/dist/types/toolAnnotations.d.ts +8 -0
  219. package/dist/types/toolAnnotations.d.ts.map +1 -0
  220. package/dist/types/toolAnnotations.js +28 -0
  221. package/dist/types/toolAnnotations.js.map +1 -0
  222. package/dist/types/toolConfig.d.ts +7 -1
  223. package/dist/types/toolConfig.d.ts.map +1 -1
  224. package/dist/types/toolConfig.js +4 -1
  225. package/dist/types/toolConfig.js.map +1 -1
  226. package/dist/utils/parseConfig.d.ts +1 -1
  227. package/dist/utils/parseConfig.d.ts.map +1 -1
  228. package/dist/utils/parseConfig.js +3 -2
  229. package/dist/utils/parseConfig.js.map +1 -1
  230. package/dist/utils/version.d.ts +2 -0
  231. package/dist/utils/version.d.ts.map +1 -0
  232. package/dist/utils/version.js +3 -0
  233. package/dist/utils/version.js.map +1 -0
  234. package/package.json +9 -3
  235. package/dist/tools/getAccount.d.ts +0 -3
  236. package/dist/tools/getAccount.d.ts.map +0 -1
  237. package/dist/tools/getAccount.js +0 -40
  238. package/dist/tools/getAccount.js.map +0 -1
  239. package/dist/tools/getCertificate.d.ts +0 -3
  240. package/dist/tools/getCertificate.d.ts.map +0 -1
  241. package/dist/tools/getCertificate.js +0 -40
  242. package/dist/tools/getCertificate.js.map +0 -1
  243. package/dist/tools/getDeploymentTarget.d.ts +0 -3
  244. package/dist/tools/getDeploymentTarget.d.ts.map +0 -1
  245. package/dist/tools/getDeploymentTarget.js +0 -66
  246. package/dist/tools/getDeploymentTarget.js.map +0 -1
  247. package/dist/tools/getReleaseById.d.ts +0 -3
  248. package/dist/tools/getReleaseById.d.ts.map +0 -1
  249. package/dist/tools/getReleaseById.js +0 -45
  250. package/dist/tools/getReleaseById.js.map +0 -1
  251. package/dist/tools/getTaskById.d.ts +0 -9
  252. package/dist/tools/getTaskById.d.ts.map +0 -1
  253. package/dist/tools/getTaskById.js +0 -44
  254. package/dist/tools/getTaskById.js.map +0 -1
  255. package/dist/tools/getTaskDetails.d.ts +0 -9
  256. package/dist/tools/getTaskDetails.d.ts.map +0 -1
  257. package/dist/tools/getTaskDetails.js +0 -44
  258. package/dist/tools/getTaskDetails.js.map +0 -1
  259. package/dist/tools/getTaskRaw.d.ts +0 -9
  260. package/dist/tools/getTaskRaw.d.ts.map +0 -1
  261. package/dist/tools/getTaskRaw.js +0 -43
  262. package/dist/tools/getTaskRaw.js.map +0 -1
  263. package/dist/tools/getTenantById.d.ts +0 -3
  264. package/dist/tools/getTenantById.d.ts.map +0 -1
  265. package/dist/tools/getTenantById.js +0 -50
  266. package/dist/tools/getTenantById.js.map +0 -1
  267. package/dist/tools/listAccounts.d.ts +0 -3
  268. package/dist/tools/listAccounts.d.ts.map +0 -1
  269. package/dist/tools/listAccounts.js +0 -54
  270. package/dist/tools/listAccounts.js.map +0 -1
  271. package/dist/tools/listCertificates.d.ts +0 -3
  272. package/dist/tools/listCertificates.d.ts.map +0 -1
  273. package/dist/tools/listCertificates.js +0 -62
  274. package/dist/tools/listCertificates.js.map +0 -1
  275. package/dist/tools/listDeploymentTargets.d.ts +0 -3
  276. package/dist/tools/listDeploymentTargets.d.ts.map +0 -1
  277. package/dist/tools/listDeploymentTargets.js +0 -98
  278. package/dist/tools/listDeploymentTargets.js.map +0 -1
  279. package/dist/tools/listReleases.d.ts +0 -3
  280. package/dist/tools/listReleases.d.ts.map +0 -1
  281. package/dist/tools/listReleases.js +0 -54
  282. package/dist/tools/listReleases.js.map +0 -1
  283. package/dist/tools/listReleasesForProject.d.ts +0 -3
  284. package/dist/tools/listReleasesForProject.d.ts.map +0 -1
  285. package/dist/tools/listReleasesForProject.js +0 -60
  286. package/dist/tools/listReleasesForProject.js.map +0 -1
  287. package/dist/tools/listTenants.d.ts +0 -3
  288. package/dist/tools/listTenants.d.ts.map +0 -1
  289. package/dist/tools/listTenants.js +0 -69
  290. package/dist/tools/listTenants.js.map +0 -1
@@ -0,0 +1,227 @@
1
+ import { Client, DeploymentRepository } from "@octopusdeploy/api-client";
2
+ import { z } from "zod";
3
+ import {} from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { getClientConfigurationFromEnvironment } from "../helpers/getClientConfigurationFromEnvironment.js";
5
+ import { registerToolDefinition } from "../types/toolConfig.js";
6
+ import { DESTRUCTIVE_WRITE_TOOL_ANNOTATIONS } from "../types/toolAnnotations.js";
7
+ import { handleOctopusApiError } from "../helpers/errorHandling.js";
8
+ import { requireConfirmation, unconfirmedResponse, } from "../helpers/requireConfirmation.js";
9
+ export function registerDeployReleaseTool(server) {
10
+ server.registerTool("deploy_release", {
11
+ title: "Deploy a release to environments in Octopus Deploy",
12
+ description: `Deploy a release to one or more environments in Octopus Deploy
13
+
14
+ This tool supports both tenanted and untenanted deployments:
15
+ - **Untenanted**: Don't provide tenants or tenantTags. Can deploy to multiple environments at once.
16
+ - **Tenanted**: Provide tenants or tenantTags. Can only deploy to ONE environment, but can target multiple tenants.
17
+
18
+ The tool automatically determines which deployment type to use based on the parameters provided.`,
19
+ inputSchema: {
20
+ spaceName: z.string().describe("The space name"),
21
+ projectName: z.string().describe("The project name"),
22
+ releaseVersion: z
23
+ .string()
24
+ .describe("The release version to deploy (e.g., '1.0.0')"),
25
+ environmentNames: z
26
+ .array(z.string())
27
+ .describe("Array of environment names. For tenanted deployments, must contain exactly one environment."),
28
+ tenants: z
29
+ .array(z.string())
30
+ .optional()
31
+ .describe("Array of tenant names for tenanted deployment (optional)"),
32
+ tenantTags: z
33
+ .array(z.string())
34
+ .optional()
35
+ .describe("Array of tenant tags for tenanted deployment (e.g., ['Region/US-West', 'Tier/Production'])"),
36
+ forcePackageRedeployment: z
37
+ .boolean()
38
+ .optional()
39
+ .describe("Force redeployment of packages"),
40
+ updateVariableSnapshot: z
41
+ .boolean()
42
+ .optional()
43
+ .describe("Update the variable snapshot"),
44
+ forcePackageDownload: z
45
+ .boolean()
46
+ .optional()
47
+ .describe("Force package download"),
48
+ specificMachineNames: z
49
+ .array(z.string())
50
+ .optional()
51
+ .describe("Deploy to specific machines only"),
52
+ excludedMachineNames: z
53
+ .array(z.string())
54
+ .optional()
55
+ .describe("Exclude specific machines from deployment"),
56
+ skipStepNames: z
57
+ .array(z.string())
58
+ .optional()
59
+ .describe("Skip specific deployment steps"),
60
+ useGuidedFailure: z
61
+ .boolean()
62
+ .optional()
63
+ .describe("Use guided failure mode"),
64
+ runAt: z
65
+ .string()
66
+ .optional()
67
+ .describe("Schedule deployment for later (ISO 8601 date string)"),
68
+ noRunAfter: z
69
+ .string()
70
+ .optional()
71
+ .describe("Don't run deployment after this time (ISO 8601 date string)"),
72
+ variables: z
73
+ .record(z.string())
74
+ .optional()
75
+ .describe("Prompted variable values as key-value pairs"),
76
+ deploymentFreezeOverrideReason: z
77
+ .string()
78
+ .optional()
79
+ .describe("Reason for overriding deployment freeze"),
80
+ deploymentFreezeNames: z
81
+ .array(z.string())
82
+ .optional()
83
+ .describe("Names of deployment freezes to override"),
84
+ confirm: z
85
+ .boolean()
86
+ .optional()
87
+ .describe("Required only when the MCP client does not support elicitation. Set to true to confirm deployment; otherwise the tool aborts."),
88
+ },
89
+ annotations: DESTRUCTIVE_WRITE_TOOL_ANNOTATIONS,
90
+ }, async ({ spaceName, projectName, releaseVersion, environmentNames, tenants, tenantTags, forcePackageRedeployment, updateVariableSnapshot, forcePackageDownload, specificMachineNames, excludedMachineNames, skipStepNames, useGuidedFailure, runAt, noRunAfter, variables, deploymentFreezeOverrideReason, deploymentFreezeNames, confirm, }) => {
91
+ try {
92
+ // Validate environment names
93
+ if (!environmentNames || environmentNames.length === 0) {
94
+ throw new Error("At least one environment name must be provided.");
95
+ }
96
+ // Determine if this is a tenanted deployment
97
+ const isTenanted = (tenants && tenants.length > 0) ||
98
+ (tenantTags && tenantTags.length > 0);
99
+ // Validate tenanted deployment constraints
100
+ if (isTenanted && environmentNames.length !== 1) {
101
+ throw new Error(`Tenanted deployments can only target one environment at a time. You provided ${environmentNames.length} environments. ` +
102
+ `For tenanted deployments, specify exactly one environment in environmentNames, then use tenants or tenantTags to target specific tenants.`);
103
+ }
104
+ const tenantSummary = isTenanted
105
+ ? ` for tenants [${(tenants ?? []).join(", ")}${tenantTags?.length ? `; tags: ${tenantTags.join(", ")}` : ""}]`
106
+ : "";
107
+ const confirmMessage = `Deploy release ${releaseVersion} of ${projectName} to ` +
108
+ `[${environmentNames.join(", ")}]${tenantSummary} in space ${spaceName}?`;
109
+ // Build common parameters
110
+ const commonParams = {
111
+ spaceName: spaceName,
112
+ ProjectName: projectName,
113
+ ...(forcePackageRedeployment !== undefined && {
114
+ ForcePackageRedeployment: forcePackageRedeployment,
115
+ }),
116
+ ...(updateVariableSnapshot !== undefined && {
117
+ UpdateVariableSnapshot: updateVariableSnapshot,
118
+ }),
119
+ ...(forcePackageDownload !== undefined && {
120
+ ForcePackageDownload: forcePackageDownload,
121
+ }),
122
+ ...(specificMachineNames && {
123
+ SpecificMachineNames: specificMachineNames,
124
+ }),
125
+ ...(excludedMachineNames && {
126
+ ExcludedMachineNames: excludedMachineNames,
127
+ }),
128
+ ...(skipStepNames && { SkipStepNames: skipStepNames }),
129
+ ...(useGuidedFailure !== undefined && {
130
+ UseGuidedFailure: useGuidedFailure,
131
+ }),
132
+ ...(runAt && { RunAt: new Date(runAt) }),
133
+ ...(noRunAfter && { NoRunAfter: new Date(noRunAfter) }),
134
+ ...(variables && { Variables: variables }),
135
+ ...(deploymentFreezeOverrideReason && {
136
+ DeploymentFreezeOverrideReason: deploymentFreezeOverrideReason,
137
+ }),
138
+ ...(deploymentFreezeNames && {
139
+ DeploymentFreezeNames: deploymentFreezeNames,
140
+ }),
141
+ };
142
+ const tenantedCommand = {
143
+ ...commonParams,
144
+ ReleaseVersion: releaseVersion,
145
+ EnvironmentName: environmentNames[0],
146
+ Tenants: tenants || [],
147
+ TenantTags: tenantTags || [],
148
+ };
149
+ const untenantedCommand = {
150
+ ...commonParams,
151
+ ReleaseVersion: releaseVersion,
152
+ EnvironmentNames: environmentNames,
153
+ };
154
+ const confirmation = await requireConfirmation(server, {
155
+ message: confirmMessage,
156
+ fallbackConfirm: confirm,
157
+ change: {
158
+ source: {},
159
+ target: isTenanted ? tenantedCommand : untenantedCommand,
160
+ },
161
+ });
162
+ if (!confirmation.confirmed) {
163
+ return unconfirmedResponse(confirmation, { action: "deployment" });
164
+ }
165
+ const configuration = getClientConfigurationFromEnvironment();
166
+ const client = await Client.create(configuration);
167
+ const deploymentRepository = new DeploymentRepository(client, spaceName);
168
+ const deploymentType = isTenanted ? "tenanted" : "untenanted";
169
+ const response = isTenanted
170
+ ? await deploymentRepository.createTenanted(tenantedCommand)
171
+ : await deploymentRepository.create(untenantedCommand);
172
+ // Format the response
173
+ const tasks = response.DeploymentServerTasks || [];
174
+ return {
175
+ content: [
176
+ {
177
+ type: "text",
178
+ text: JSON.stringify({
179
+ success: true,
180
+ deploymentType,
181
+ deploymentsCreated: tasks.length,
182
+ deploymentTasks: tasks.map((task) => ({
183
+ taskId: task.ServerTaskId,
184
+ deploymentId: task.DeploymentId,
185
+ })),
186
+ message: `Successfully created ${tasks.length} deployment(s) for release ${releaseVersion}`,
187
+ helpText: `Fetch octopus://spaces/{spaceName}/tasks/{taskId} (or /details for the structured activity tree) via resources/read or read_resource to monitor deployment progress. To search the raw log for a specific error or step, call grep_task_log with the taskId. Use list_deployments for high-level deployment listings.`,
188
+ }, null, 2),
189
+ },
190
+ ],
191
+ };
192
+ }
193
+ catch (error) {
194
+ // Handle validation errors from our code
195
+ if (error instanceof Error && !error.message.includes("octopus")) {
196
+ return {
197
+ content: [
198
+ {
199
+ type: "text",
200
+ text: JSON.stringify({
201
+ success: false,
202
+ error: error.message,
203
+ }, null, 2),
204
+ },
205
+ ],
206
+ isError: true,
207
+ };
208
+ }
209
+ // Handle Octopus API errors
210
+ handleOctopusApiError(error, {
211
+ entityType: "deployment",
212
+ spaceName,
213
+ helpText: "Use list_projects to find valid project names, list_environments for environment names, find_releases to verify the release exists, and find_tenants for tenant information. Ensure you have permissions to create deployments.",
214
+ });
215
+ }
216
+ });
217
+ }
218
+ registerToolDefinition({
219
+ toolName: "deploy_release",
220
+ config: { toolset: "deployments", readOnly: false },
221
+ registerFn: registerDeployReleaseTool,
222
+ // DeploymentRepository.create / .createTenanted use the Executions API
223
+ // (~/api/{space}/deployments/create/v1 and /create/tenanted/v1-alpha) which
224
+ // the api-client refuses to call against servers older than 2022.3.5512.
225
+ minimumOctopusVersion: "2022.3.5512",
226
+ });
227
+ //# sourceMappingURL=deployRelease.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployRelease.js","sourceRoot":"","sources":["../../src/tools/deployRelease.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerExecuteTool(server: McpServer): void;
3
+ //# sourceMappingURL=execute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/tools/execute.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAsKzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,QAmLpD"}
@@ -0,0 +1,261 @@
1
+ import { Client } from "@octopusdeploy/api-client";
2
+ import { z } from "zod";
3
+ import {} from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { registerToolDefinition } from "../types/toolConfig.js";
5
+ import { DESTRUCTIVE_WRITE_TOOL_ANNOTATIONS } from "../types/toolAnnotations.js";
6
+ import { getClientConfigurationFromEnvironment } from "../helpers/getClientConfigurationFromEnvironment.js";
7
+ import { HTTP_METHODS, classifyMethod, } from "../helpers/methodTier.js";
8
+ import { isSensitive } from "../helpers/sensitivePathDenylist.js";
9
+ import { matchPath, findOwningToolset } from "../helpers/pathAllowlist.js";
10
+ import { validateExecutePath } from "../helpers/validateExecutePath.js";
11
+ import { requireConfirmation, unconfirmedResponse, } from "../helpers/requireConfirmation.js";
12
+ import { getActiveToolsetConfig } from "../helpers/activeToolsetConfig.js";
13
+ import { DEFAULT_TOOLSETS, } from "../types/toolConfig.js";
14
+ function errorResponse(payload) {
15
+ return {
16
+ content: [
17
+ {
18
+ type: "text",
19
+ text: JSON.stringify(payload, null, 2),
20
+ },
21
+ ],
22
+ isError: true,
23
+ };
24
+ }
25
+ function summariseBody(body) {
26
+ if (body == null)
27
+ return "(no body)";
28
+ if (typeof body === "string") {
29
+ return body.length > 200 ? `${body.slice(0, 200)}…` : body;
30
+ }
31
+ try {
32
+ const json = JSON.stringify(body);
33
+ if (json.length <= 400)
34
+ return json;
35
+ return `${json.slice(0, 400)}… (${json.length} bytes total)`;
36
+ }
37
+ catch {
38
+ return "(unserialisable body)";
39
+ }
40
+ }
41
+ /**
42
+ * Build a one-shot audit emitter scoped to a single execute call. Captures
43
+ * the start time so callers only state outcome + reason — no need to repeat
44
+ * method/tier/path/durationMs at every gate. Stub on stderr; replace with the
45
+ * structured emitter from AIF-357 once it lands.
46
+ */
47
+ function startAudit(call) {
48
+ const startedAt = Date.now();
49
+ return (outcome, reason) => {
50
+ process.stderr.write(JSON.stringify({
51
+ ts: new Date().toISOString(),
52
+ tool: "execute",
53
+ ...call,
54
+ outcome,
55
+ ...(reason !== undefined ? { reason } : {}),
56
+ durationMs: Date.now() - startedAt,
57
+ }) + "\n");
58
+ };
59
+ }
60
+ function resolveEnabledToolsets() {
61
+ const config = getActiveToolsetConfig();
62
+ if (config.enabledToolsets === "all" || config.enabledToolsets == null) {
63
+ return DEFAULT_TOOLSETS;
64
+ }
65
+ return config.enabledToolsets;
66
+ }
67
+ async function dispatchExecute(client, method, path, query, body) {
68
+ const dispatchable = client;
69
+ const url = dispatchable.resolveUrl(path, query);
70
+ return dispatchable.dispatchRequest(method, url, body ?? null);
71
+ }
72
+ const inputSchema = {
73
+ method: z
74
+ .enum(HTTP_METHODS)
75
+ .describe("HTTP method. The method itself is the read/write/delete classifier — GET is read-only, POST/PUT/PATCH are blocked when --read-only is set, DELETE additionally requires --allow-deletes. The agent cannot bypass this by lying about intent."),
76
+ path: z
77
+ .string()
78
+ .min(1)
79
+ .describe("Path under the configured Octopus server, e.g. '/api/spaces/Spaces-1/feeds' or '/api/Spaces-1/projects'. Discover paths via grep_llms_txt."),
80
+ query: z
81
+ .record(z.string())
82
+ .optional()
83
+ .describe("Optional query-string parameters as a flat object."),
84
+ body: z
85
+ .unknown()
86
+ .optional()
87
+ .describe("Optional request body for POST/PUT/PATCH calls."),
88
+ asCsv: z
89
+ .boolean()
90
+ .optional()
91
+ .describe("If true, request 'text/csv' for tabular GET responses. The Octopus API honours this for endpoints that support CSV output."),
92
+ confirm: z
93
+ .boolean()
94
+ .optional()
95
+ .describe("Required only when the MCP client does not support elicitation. Set to true to confirm a non-GET call; otherwise the tool aborts."),
96
+ };
97
+ export function registerExecuteTool(server) {
98
+ server.registerTool("execute", {
99
+ title: "Execute an Octopus REST request (backstop)",
100
+ description: `Reach Octopus REST endpoints not covered by the curated tools. Use this only after grep_llms_txt has shown you the right method and path.
101
+
102
+ **Method gating is hard-coded server-side, three tiers:**
103
+
104
+ - GET → read tier: always allowed (subject to toolset allowlist + sensitive denylist).
105
+ - POST/PUT/PATCH → write tier: blocked when --read-only is set; requires user confirmation via elicitation otherwise.
106
+ - DELETE → delete tier: requires --allow-deletes (and is blocked when --read-only is set) AND a stronger user confirmation.
107
+
108
+ The HTTP method enum is the gate. The tool will not honour any 'isRead' flag the agent invents — the runtime classifies based on the actual method.
109
+
110
+ **Other gates** (in order):
111
+ 1. Sensitive denylist: API key endpoints and catastrophic deletes (DELETE /api/users/{id}, DELETE /api/spaces/{id}) are always blocked.
112
+ 2. Path allowlist by enabled toolset: paths only resolve if their owning toolset is enabled. Disabling a toolset (e.g. 'certificates') makes its endpoints unreachable even on GET.
113
+ 3. Elicitation on every non-GET, with a stronger message for DELETE.
114
+
115
+ Discover endpoints with grep_llms_txt. Use octopus://api/capabilities to see which toolsets are enabled and whether write/delete modes are on.`,
116
+ inputSchema,
117
+ annotations: DESTRUCTIVE_WRITE_TOOL_ANNOTATIONS,
118
+ }, async (args) => {
119
+ const params = args;
120
+ const { method, path: rawPath, query, body, asCsv } = params;
121
+ const tier = classifyMethod(method);
122
+ const audit = startAudit({ method, tier, path: rawPath });
123
+ const config = getActiveToolsetConfig();
124
+ const readOnlyMode = config.readOnlyMode ?? false;
125
+ const allowDeletes = config.allowDeletes ?? false;
126
+ // Gate 0: path canonicalization. Reject paths that can mean different
127
+ // things to the allowlist matcher and the HTTP client (`..` traversal,
128
+ // encoded slashes, query strings, fragments, backslashes). Runs FIRST
129
+ // so a traversal attempt cannot pass any later gate.
130
+ const validation = validateExecutePath(rawPath);
131
+ if (!validation.ok) {
132
+ audit("blocked", "invalidPath");
133
+ return errorResponse({
134
+ success: false,
135
+ reason: "invalidPath",
136
+ message: `Invalid path: ${validation.reason}`,
137
+ });
138
+ }
139
+ const path = validation.path;
140
+ // Gate 1: sensitive denylist (always-on, applies regardless of mode).
141
+ const sensitive = isSensitive(method, path);
142
+ if (sensitive.blocked) {
143
+ audit("blocked", "sensitivePath");
144
+ return errorResponse({
145
+ success: false,
146
+ reason: "sensitivePath",
147
+ message: `Path '${path}' is on the sensitive denylist and cannot be reached via execute. ${sensitive.reason ?? ""}`.trim(),
148
+ });
149
+ }
150
+ // Gate 2: tier-based mode gate.
151
+ if (tier === "write" && readOnlyMode) {
152
+ audit("blocked", "readOnlyMode");
153
+ return errorResponse({
154
+ success: false,
155
+ reason: "readOnlyMode",
156
+ message: "This server is in read-only mode. Restart without --read-only to enable write requests through the execute tool.",
157
+ });
158
+ }
159
+ if (tier === "delete") {
160
+ if (readOnlyMode) {
161
+ audit("blocked", "readOnlyMode");
162
+ return errorResponse({
163
+ success: false,
164
+ reason: "readOnlyMode",
165
+ message: "This server is in read-only mode. Restart without --read-only AND with --allow-deletes to permit DELETE requests through the execute tool.",
166
+ });
167
+ }
168
+ if (!allowDeletes) {
169
+ audit("blocked", "deletesNotAllowed");
170
+ return errorResponse({
171
+ success: false,
172
+ reason: "deletesNotAllowed",
173
+ message: "DELETE requests are not permitted. Restart with --allow-deletes to enable them. This is a deliberate opt-in for irreversible operations.",
174
+ });
175
+ }
176
+ }
177
+ // Gate 3: path allowlist by enabled toolset.
178
+ const enabledToolsets = resolveEnabledToolsets();
179
+ const allowed = matchPath(path, enabledToolsets);
180
+ if (!allowed.matched) {
181
+ const owner = findOwningToolset(path);
182
+ audit("blocked", "pathNotAllowed");
183
+ return errorResponse({
184
+ success: false,
185
+ reason: "pathNotAllowed",
186
+ message: owner
187
+ ? `Path '${path}' belongs to the '${owner}' toolset which is not enabled in this session. Enable it via --toolsets to reach this endpoint.`
188
+ : `Path '${path}' is not on the execute allowlist for any toolset. If this is a legitimate Octopus endpoint not yet covered, file an issue against the MCP server.`,
189
+ });
190
+ }
191
+ // Gate 4: elicitation on every non-GET.
192
+ if (tier !== "read") {
193
+ const isDelete = tier === "delete";
194
+ const message = isDelete
195
+ ? `IRREVERSIBLE delete operation. Confirm carefully.\n\n${method} ${path}\nQuery: ${JSON.stringify(query ?? {})}\nBody: ${summariseBody(body)}`
196
+ : `${method} ${path}\nQuery: ${JSON.stringify(query ?? {})}\nBody: ${summariseBody(body)}`;
197
+ const confirmation = await requireConfirmation(server, {
198
+ message,
199
+ fallbackConfirm: params.confirm,
200
+ });
201
+ if (!confirmation.confirmed) {
202
+ audit("cancelled", confirmation.reason);
203
+ return unconfirmedResponse(confirmation, {
204
+ action: isDelete ? "deletion" : "API call",
205
+ });
206
+ }
207
+ }
208
+ // All gates passed. Dispatch.
209
+ try {
210
+ const client = await Client.create(getClientConfigurationFromEnvironment());
211
+ const requestQuery = asCsv
212
+ ? { ...(query ?? {}), format: "csv" }
213
+ : query;
214
+ const result = await dispatchExecute(client, method, path, requestQuery, body);
215
+ audit("ok");
216
+ return {
217
+ content: [
218
+ {
219
+ type: "text",
220
+ text: JSON.stringify({
221
+ success: true,
222
+ method,
223
+ path,
224
+ tier,
225
+ response: result,
226
+ }),
227
+ },
228
+ ],
229
+ };
230
+ }
231
+ catch (error) {
232
+ const message = error instanceof Error ? error.message : String(error);
233
+ audit("error", message);
234
+ return {
235
+ content: [
236
+ {
237
+ type: "text",
238
+ text: JSON.stringify({
239
+ success: false,
240
+ reason: "octopusError",
241
+ method,
242
+ path,
243
+ tier,
244
+ message,
245
+ }, null, 2),
246
+ },
247
+ ],
248
+ isError: true,
249
+ };
250
+ }
251
+ });
252
+ }
253
+ registerToolDefinition({
254
+ toolName: "execute",
255
+ // readOnly: true so the tool is registered even in --read-only mode (where
256
+ // only its GET branch is reachable). Method-tier gating inside the handler
257
+ // enforces the actual write/delete policy at runtime.
258
+ config: { toolset: "core", readOnly: true },
259
+ registerFn: registerExecuteTool,
260
+ });
261
+ //# sourceMappingURL=execute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/tools/execute.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerFindAccountsTool(server: McpServer): void;
3
+ //# sourceMappingURL=findAccounts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findAccounts.d.ts","sourceRoot":"","sources":["../../src/tools/findAccounts.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAWzE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,QAmGzD"}
@@ -0,0 +1,90 @@
1
+ import { Client, resolveSpaceId } from "@octopusdeploy/api-client";
2
+ import { z } from "zod";
3
+ import {} from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { registerToolDefinition } from "../types/toolConfig.js";
5
+ import { READ_ONLY_TOOL_ANNOTATIONS } from "../types/toolAnnotations.js";
6
+ import { getClientConfigurationFromEnvironment } from "../helpers/getClientConfigurationFromEnvironment.js";
7
+ import { mapAccountResource, AccountType } from "../types/accountTypes.js";
8
+ import { validateEntityId, handleOctopusApiError, ENTITY_PREFIXES } from "../helpers/errorHandling.js";
9
+ export function registerFindAccountsTool(server) {
10
+ server.registerTool("find_accounts", {
11
+ title: "Find accounts in an Octopus Deploy space",
12
+ description: `Find accounts in a space - can retrieve a single account by ID or list all accounts
13
+
14
+ This unified tool can either:
15
+ - Get detailed information about a specific account when accountId is provided
16
+ - List all accounts in a space when accountId is omitted
17
+
18
+ You can optionally filter by various parameters like name, account type, etc. when listing.`,
19
+ inputSchema: {
20
+ spaceName: z.string(),
21
+ accountId: z.string().optional().describe("The ID of a specific account to retrieve. If omitted, lists all accounts."),
22
+ skip: z.number().optional().describe("Number of accounts to skip for pagination (only used when listing)"),
23
+ take: z.number().optional().describe("Number of accounts to take for pagination (only used when listing)"),
24
+ ids: z.array(z.string()).optional().describe("Filter by specific account IDs (only used when listing)"),
25
+ partialName: z.string().optional().describe("Filter by partial name match (only used when listing)"),
26
+ accountType: z.nativeEnum(AccountType).optional().describe("Filter by account type (only used when listing)"),
27
+ },
28
+ annotations: READ_ONLY_TOOL_ANNOTATIONS,
29
+ }, async ({ spaceName, accountId, skip, take, ids, partialName, accountType, }) => {
30
+ const configuration = getClientConfigurationFromEnvironment();
31
+ const client = await Client.create(configuration);
32
+ const spaceId = await resolveSpaceId(client, spaceName);
33
+ // If accountId is provided, get a single account
34
+ if (accountId) {
35
+ validateEntityId(accountId, 'account', ENTITY_PREFIXES.account);
36
+ try {
37
+ const response = await client.get("~/api/{spaceId}/accounts/{id}", {
38
+ spaceId,
39
+ id: accountId,
40
+ });
41
+ const account = mapAccountResource(response);
42
+ return {
43
+ content: [
44
+ {
45
+ type: "text",
46
+ text: JSON.stringify(account),
47
+ },
48
+ ],
49
+ };
50
+ }
51
+ catch (error) {
52
+ handleOctopusApiError(error, {
53
+ entityType: 'account',
54
+ entityId: accountId,
55
+ spaceName
56
+ });
57
+ }
58
+ }
59
+ // Otherwise, list all accounts
60
+ const response = await client.get("~/api/{spaceId}/accounts{?skip,take,ids,partialName,accountType}", {
61
+ spaceId,
62
+ skip,
63
+ take,
64
+ ids,
65
+ partialName,
66
+ accountType,
67
+ });
68
+ const accounts = response.Items.map((account) => mapAccountResource(account));
69
+ return {
70
+ content: [
71
+ {
72
+ type: "text",
73
+ text: JSON.stringify({
74
+ totalResults: response.TotalResults,
75
+ itemsPerPage: response.ItemsPerPage,
76
+ numberOfPages: response.NumberOfPages,
77
+ lastPageNumber: response.LastPageNumber,
78
+ items: accounts,
79
+ }),
80
+ },
81
+ ],
82
+ };
83
+ });
84
+ }
85
+ registerToolDefinition({
86
+ toolName: "find_accounts",
87
+ config: { toolset: "accounts", readOnly: true },
88
+ registerFn: registerFindAccountsTool,
89
+ });
90
+ //# sourceMappingURL=findAccounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findAccounts.js","sourceRoot":"","sources":["../../src/tools/findAccounts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerFindCertificatesTool(server: McpServer): void;
3
+ //# sourceMappingURL=findCertificates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findCertificates.d.ts","sourceRoot":"","sources":["../../src/tools/findCertificates.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,QA+G7D"}