@octopusdeploy/mcp-server 1.1.0 → 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 (231) hide show
  1. package/README.md +202 -47
  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 +3 -0
  7. package/dist/helpers/errorHandling.d.ts.map +1 -1
  8. package/dist/helpers/errorHandling.js +4 -1
  9. package/dist/helpers/errorHandling.js.map +1 -1
  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 +20 -4
  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/stripLinks.d.ts +15 -0
  39. package/dist/helpers/stripLinks.d.ts.map +1 -0
  40. package/dist/helpers/stripLinks.js +19 -0
  41. package/dist/helpers/stripLinks.js.map +1 -0
  42. package/dist/helpers/userCache.d.ts +14 -0
  43. package/dist/helpers/userCache.d.ts.map +1 -0
  44. package/dist/helpers/userCache.js +16 -0
  45. package/dist/helpers/userCache.js.map +1 -0
  46. package/dist/helpers/validateExecutePath.d.ts +29 -0
  47. package/dist/helpers/validateExecutePath.d.ts.map +1 -0
  48. package/dist/helpers/validateExecutePath.js +62 -0
  49. package/dist/helpers/validateExecutePath.js.map +1 -0
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +58 -9
  52. package/dist/index.js.map +1 -1
  53. package/dist/resources/catalog/capabilities.d.ts +36 -0
  54. package/dist/resources/catalog/capabilities.d.ts.map +1 -0
  55. package/dist/resources/catalog/capabilities.js +90 -0
  56. package/dist/resources/catalog/capabilities.js.map +1 -0
  57. package/dist/resources/catalog/llmsTxt.d.ts +8 -0
  58. package/dist/resources/catalog/llmsTxt.d.ts.map +1 -0
  59. package/dist/resources/catalog/llmsTxt.js +44 -0
  60. package/dist/resources/catalog/llmsTxt.js.map +1 -0
  61. package/dist/resources/dispatch.d.ts +30 -0
  62. package/dist/resources/dispatch.d.ts.map +1 -0
  63. package/dist/resources/dispatch.js +81 -0
  64. package/dist/resources/dispatch.js.map +1 -0
  65. package/dist/resources/featureToggle.d.ts +2 -0
  66. package/dist/resources/featureToggle.d.ts.map +1 -0
  67. package/dist/resources/featureToggle.js +34 -0
  68. package/dist/resources/featureToggle.js.map +1 -0
  69. package/dist/resources/index.d.ts +12 -0
  70. package/dist/resources/index.d.ts.map +1 -0
  71. package/dist/resources/index.js +44 -0
  72. package/dist/resources/index.js.map +1 -0
  73. package/dist/resources/interruption.d.ts +2 -0
  74. package/dist/resources/interruption.d.ts.map +1 -0
  75. package/dist/resources/interruption.js +34 -0
  76. package/dist/resources/interruption.js.map +1 -0
  77. package/dist/resources/release.d.ts +2 -0
  78. package/dist/resources/release.d.ts.map +1 -0
  79. package/dist/resources/release.js +33 -0
  80. package/dist/resources/release.js.map +1 -0
  81. package/dist/resources/rolloutGroup.d.ts +2 -0
  82. package/dist/resources/rolloutGroup.d.ts.map +1 -0
  83. package/dist/resources/rolloutGroup.js +35 -0
  84. package/dist/resources/rolloutGroup.js.map +1 -0
  85. package/dist/resources/runbook.d.ts +2 -0
  86. package/dist/resources/runbook.d.ts.map +1 -0
  87. package/dist/resources/runbook.js +34 -0
  88. package/dist/resources/runbook.js.map +1 -0
  89. package/dist/resources/task.d.ts +2 -0
  90. package/dist/resources/task.d.ts.map +1 -0
  91. package/dist/resources/task.js +68 -0
  92. package/dist/resources/task.js.map +1 -0
  93. package/dist/tools/createRelease.d.ts.map +1 -1
  94. package/dist/tools/createRelease.js +93 -50
  95. package/dist/tools/createRelease.js.map +1 -1
  96. package/dist/tools/deployRelease.d.ts.map +1 -1
  97. package/dist/tools/deployRelease.js +117 -97
  98. package/dist/tools/deployRelease.js.map +1 -1
  99. package/dist/tools/execute.d.ts +3 -0
  100. package/dist/tools/execute.d.ts.map +1 -0
  101. package/dist/tools/execute.js +261 -0
  102. package/dist/tools/execute.js.map +1 -0
  103. package/dist/tools/findAccounts.d.ts.map +1 -1
  104. package/dist/tools/findAccounts.js +15 -12
  105. package/dist/tools/findAccounts.js.map +1 -1
  106. package/dist/tools/findCertificates.d.ts.map +1 -1
  107. package/dist/tools/findCertificates.js +19 -16
  108. package/dist/tools/findCertificates.js.map +1 -1
  109. package/dist/tools/findDeploymentTargets.d.ts.map +1 -1
  110. package/dist/tools/findDeploymentTargets.js +26 -23
  111. package/dist/tools/findDeploymentTargets.js.map +1 -1
  112. package/dist/tools/findFeatureToggles.d.ts +37 -0
  113. package/dist/tools/findFeatureToggles.d.ts.map +1 -0
  114. package/dist/tools/findFeatureToggles.js +139 -0
  115. package/dist/tools/findFeatureToggles.js.map +1 -0
  116. package/dist/tools/findInterruptions.d.ts +79 -0
  117. package/dist/tools/findInterruptions.d.ts.map +1 -0
  118. package/dist/tools/findInterruptions.js +273 -0
  119. package/dist/tools/findInterruptions.js.map +1 -0
  120. package/dist/tools/findReleases.d.ts.map +1 -1
  121. package/dist/tools/findReleases.js +90 -48
  122. package/dist/tools/findReleases.js.map +1 -1
  123. package/dist/tools/findRunbooks.d.ts +3 -0
  124. package/dist/tools/findRunbooks.d.ts.map +1 -0
  125. package/dist/tools/findRunbooks.js +139 -0
  126. package/dist/tools/findRunbooks.js.map +1 -0
  127. package/dist/tools/findTenants.d.ts.map +1 -1
  128. package/dist/tools/findTenants.js +28 -25
  129. package/dist/tools/findTenants.js.map +1 -1
  130. package/dist/tools/getBranches.d.ts.map +1 -1
  131. package/dist/tools/getBranches.js +13 -10
  132. package/dist/tools/getBranches.js.map +1 -1
  133. package/dist/tools/getCurrentUser.d.ts.map +1 -1
  134. package/dist/tools/getCurrentUser.js +7 -4
  135. package/dist/tools/getCurrentUser.js.map +1 -1
  136. package/dist/tools/getDeploymentFromUrl.d.ts +8 -3
  137. package/dist/tools/getDeploymentFromUrl.d.ts.map +1 -1
  138. package/dist/tools/getDeploymentFromUrl.js +46 -18
  139. package/dist/tools/getDeploymentFromUrl.js.map +1 -1
  140. package/dist/tools/getDeploymentProcess.d.ts.map +1 -1
  141. package/dist/tools/getDeploymentProcess.js +26 -23
  142. package/dist/tools/getDeploymentProcess.js.map +1 -1
  143. package/dist/tools/getKubernetesLiveStatus.d.ts.map +1 -1
  144. package/dist/tools/getKubernetesLiveStatus.js +13 -10
  145. package/dist/tools/getKubernetesLiveStatus.js.map +1 -1
  146. package/dist/tools/getMissingTenantVariables.d.ts.map +1 -1
  147. package/dist/tools/getMissingTenantVariables.js +13 -10
  148. package/dist/tools/getMissingTenantVariables.js.map +1 -1
  149. package/dist/tools/getTaskFromUrl.d.ts +2 -3
  150. package/dist/tools/getTaskFromUrl.d.ts.map +1 -1
  151. package/dist/tools/getTaskFromUrl.js +33 -33
  152. package/dist/tools/getTaskFromUrl.js.map +1 -1
  153. package/dist/tools/getTenantVariables.d.ts.map +1 -1
  154. package/dist/tools/getTenantVariables.js +13 -10
  155. package/dist/tools/getTenantVariables.js.map +1 -1
  156. package/dist/tools/getVariables.d.ts.map +1 -1
  157. package/dist/tools/getVariables.js +12 -9
  158. package/dist/tools/getVariables.js.map +1 -1
  159. package/dist/tools/grepLlmsTxt.d.ts +13 -0
  160. package/dist/tools/grepLlmsTxt.d.ts.map +1 -0
  161. package/dist/tools/grepLlmsTxt.js +105 -0
  162. package/dist/tools/grepLlmsTxt.js.map +1 -0
  163. package/dist/tools/grepTaskLog.d.ts +30 -0
  164. package/dist/tools/grepTaskLog.d.ts.map +1 -0
  165. package/dist/tools/grepTaskLog.js +116 -0
  166. package/dist/tools/grepTaskLog.js.map +1 -0
  167. package/dist/tools/index.d.ts +9 -4
  168. package/dist/tools/index.d.ts.map +1 -1
  169. package/dist/tools/index.js +14 -4
  170. package/dist/tools/index.js.map +1 -1
  171. package/dist/tools/listDeployments.d.ts.map +1 -1
  172. package/dist/tools/listDeployments.js +22 -13
  173. package/dist/tools/listDeployments.js.map +1 -1
  174. package/dist/tools/listEnvironments.d.ts.map +1 -1
  175. package/dist/tools/listEnvironments.js +12 -9
  176. package/dist/tools/listEnvironments.js.map +1 -1
  177. package/dist/tools/listProjects.d.ts.map +1 -1
  178. package/dist/tools/listProjects.js +10 -7
  179. package/dist/tools/listProjects.js.map +1 -1
  180. package/dist/tools/listSpaces.d.ts.map +1 -1
  181. package/dist/tools/listSpaces.js +9 -6
  182. package/dist/tools/listSpaces.js.map +1 -1
  183. package/dist/tools/readResource.d.ts +3 -0
  184. package/dist/tools/readResource.d.ts.map +1 -0
  185. package/dist/tools/readResource.js +50 -0
  186. package/dist/tools/readResource.js.map +1 -0
  187. package/dist/tools/runRunbook.d.ts +3 -0
  188. package/dist/tools/runRunbook.d.ts.map +1 -0
  189. package/dist/tools/runRunbook.js +174 -0
  190. package/dist/tools/runRunbook.js.map +1 -0
  191. package/dist/tools/updateFeatureToggle.d.ts +94 -0
  192. package/dist/tools/updateFeatureToggle.d.ts.map +1 -0
  193. package/dist/tools/updateFeatureToggle.js +308 -0
  194. package/dist/tools/updateFeatureToggle.js.map +1 -0
  195. package/dist/types/featureToggleTypes.d.ts +47 -0
  196. package/dist/types/featureToggleTypes.d.ts.map +1 -0
  197. package/dist/types/featureToggleTypes.js +10 -0
  198. package/dist/types/featureToggleTypes.js.map +1 -0
  199. package/dist/types/resourceConfig.d.ts +17 -0
  200. package/dist/types/resourceConfig.d.ts.map +1 -0
  201. package/dist/types/resourceConfig.js +6 -0
  202. package/dist/types/resourceConfig.js.map +1 -0
  203. package/dist/types/toolAnnotations.d.ts +8 -0
  204. package/dist/types/toolAnnotations.d.ts.map +1 -0
  205. package/dist/types/toolAnnotations.js +28 -0
  206. package/dist/types/toolAnnotations.js.map +1 -0
  207. package/dist/types/toolConfig.d.ts +7 -1
  208. package/dist/types/toolConfig.d.ts.map +1 -1
  209. package/dist/types/toolConfig.js +4 -1
  210. package/dist/types/toolConfig.js.map +1 -1
  211. package/dist/utils/parseConfig.d.ts +1 -1
  212. package/dist/utils/parseConfig.d.ts.map +1 -1
  213. package/dist/utils/parseConfig.js +3 -2
  214. package/dist/utils/parseConfig.js.map +1 -1
  215. package/package.json +4 -4
  216. package/dist/tools/getTaskById.d.ts +0 -9
  217. package/dist/tools/getTaskById.d.ts.map +0 -1
  218. package/dist/tools/getTaskById.js +0 -51
  219. package/dist/tools/getTaskById.js.map +0 -1
  220. package/dist/tools/getTaskDetails.d.ts +0 -9
  221. package/dist/tools/getTaskDetails.d.ts.map +0 -1
  222. package/dist/tools/getTaskDetails.js +0 -65
  223. package/dist/tools/getTaskDetails.js.map +0 -1
  224. package/dist/tools/getTaskRaw.d.ts +0 -9
  225. package/dist/tools/getTaskRaw.d.ts.map +0 -1
  226. package/dist/tools/getTaskRaw.js +0 -50
  227. package/dist/tools/getTaskRaw.js.map +0 -1
  228. package/dist/tools/listReleasesForProject.d.ts +0 -3
  229. package/dist/tools/listReleasesForProject.d.ts.map +0 -1
  230. package/dist/tools/listReleasesForProject.js +0 -60
  231. package/dist/tools/listReleasesForProject.js.map +0 -1
package/README.md CHANGED
@@ -20,14 +20,10 @@ Most tools exposed by the MCP Server use stable APIs that have been available fr
20
20
 
21
21
  ### Install via Docker
22
22
 
23
- Run with environment variables
24
- ```bash
25
- docker run -i --rm -e OCTOPUS_API_KEY=your-key -e OCTOPUS_SERVER_URL=https://your-octopus.com octopusdeploy/mcp-server
26
- ```
23
+ Credentials must be supplied via environment variables to avoid exposing them in the host process list (`ps aux` / `/proc/<pid>/cmdline`). The Octopus server URL can still be supplied via the `--server-url` flag.
27
24
 
28
- Run with CLI arguments
29
25
  ```bash
30
- docker run -i --rm octopusdeploy/mcp-server --server-url https://your-octopus.com --api-key YOUR_API_KEY
26
+ docker run -i --rm -e OCTOPUS_API_KEY=your-key -e OCTOPUS_SERVER_URL=https://your-octopus.com octopusdeploy/mcp-server
31
27
  ```
32
28
 
33
29
  Full example configuration (for Claude Desktop, Claude Code, and Cursor):
@@ -41,12 +37,16 @@ Full example configuration (for Claude Desktop, Claude Code, and Cursor):
41
37
  "run",
42
38
  "-i",
43
39
  "--rm",
44
- "octopusdeploy/mcp-server",
45
- "--server-url",
46
- "https://your-octopus.com",
47
- "--api-key",
48
- "YOUR_API_KEY"
49
- ]
40
+ "-e",
41
+ "OCTOPUS_SERVER_URL",
42
+ "-e",
43
+ "OCTOPUS_API_KEY",
44
+ "octopusdeploy/mcp-server"
45
+ ],
46
+ "env": {
47
+ "OCTOPUS_SERVER_URL": "https://your-octopus.com",
48
+ "OCTOPUS_API_KEY": "YOUR_API_KEY"
49
+ }
50
50
  },
51
51
  }
52
52
  }
@@ -65,59 +65,105 @@ We are planning to release a native ARM build shortly so that those arguments wi
65
65
  #### Requirements
66
66
  - Node.js >= v20.0.0
67
67
  - Octopus Deploy instance that can be accessed by the MCP server via HTTPS
68
- - Octopus Deploy API Key
68
+ - Octopus Deploy API Key or Access Token (see [Authentication](#authentication) below)
69
69
 
70
70
  #### Configuration
71
71
 
72
72
  Full example configuration (for Claude Desktop, Claude Code, and Cursor):
73
73
 
74
- **Read-only mode (default, recommended for production):**
74
+ **Write tools enabled (default):**
75
75
  ```json
76
76
  {
77
77
  "mcpServers": {
78
78
  "octopusdeploy": {
79
79
  "type": "stdio",
80
80
  "command": "npx",
81
- "args": ["-y", "@octopusdeploy/mcp-server", "--api-key", "YOUR_API_KEY", "--server-url", "https://your-octopus.com"]
81
+ "args": ["-y", "@octopusdeploy/mcp-server"],
82
+ "env": {
83
+ "OCTOPUS_SERVER_URL": "https://your-octopus.com",
84
+ "OCTOPUS_API_KEY": "YOUR_API_KEY"
85
+ }
82
86
  }
83
87
  }
84
88
  }
85
89
  ```
86
90
 
87
- **Write mode enabled (for development/testing):**
91
+ **Read-only mode (recommended for production):**
88
92
  ```json
89
93
  {
90
94
  "mcpServers": {
91
95
  "octopusdeploy": {
92
96
  "type": "stdio",
93
97
  "command": "npx",
94
- "args": ["-y", "@octopusdeploy/mcp-server", "--api-key", "YOUR_API_KEY", "--server-url", "https://your-octopus.com", "--no-read-only"]
98
+ "args": ["-y", "@octopusdeploy/mcp-server", "--read-only"],
99
+ "env": {
100
+ "OCTOPUS_SERVER_URL": "https://your-octopus.com",
101
+ "OCTOPUS_API_KEY": "YOUR_API_KEY"
102
+ }
95
103
  }
96
104
  }
97
105
  }
98
106
  ```
99
107
 
100
- The Octopus MCP Server is typically configured within your AI Client of choice.
108
+ The Octopus MCP Server is typically configured within your AI Client of choice.
101
109
 
102
- It is packaged as an npm package and executed via Node's `npx` command. Your configuration will include the command invocation `npx`, and a set of arguments that supply the Octopus MCP Server package and provide the Octopus Server URL and API key required, if they are not available as environment variables.
103
-
104
- The command line invocation you will be configuring will be one of the two following variants:
110
+ It is packaged as an npm package and executed via Node's `npx` command. Credentials (API key or access token) must be supplied via environment variables they are not accepted as command-line arguments to avoid exposing secrets in the process list. The Octopus server URL may be supplied via either the `OCTOPUS_SERVER_URL` environment variable or the `--server-url` flag.
105
111
 
106
112
  ```bash
113
+ OCTOPUS_API_KEY=API-KEY \
114
+ OCTOPUS_SERVER_URL=https://your-octopus.com \
107
115
  npx -y @octopusdeploy/mcp-server
108
116
  ```
109
117
 
110
- With configuration provided via environment variables:
118
+ Or with the server URL on the command line:
119
+ ```bash
120
+ OCTOPUS_API_KEY=API-KEY \
121
+ npx -y @octopusdeploy/mcp-server --server-url https://your-octopus.com
122
+ ```
123
+
124
+ ### Authentication
125
+
126
+ The MCP server supports two authentication methods. Both are supplied via environment variables — credentials are not accepted on the command line because flags are visible in the host process list to any local user.
127
+
128
+ #### API Key (recommended for interactive use)
129
+
130
+ API keys are the standard authentication method for Octopus Deploy. You can generate one from your Octopus Deploy user profile.
131
+
111
132
  ```bash
112
- OCTOPUS_API_KEY=API-KEY
113
- OCTOPUS_SERVER_URL=https://your-octopus.com
133
+ OCTOPUS_API_KEY=API-XXXXXXXXXXXXXXXXXXXXXXXXXX \
134
+ OCTOPUS_SERVER_URL=https://your-octopus.com \
135
+ npx -y @octopusdeploy/mcp-server
114
136
  ```
115
137
 
116
- Or with configuration supplied via the command line:
138
+ #### Access Token / Bearer Token (automated scenarios only)
139
+
140
+ The server also supports short-lived access tokens (Bearer tokens) as an alternative to API keys. This authentication method is intended **only for automated scenarios** where an external system issues a short-lived token to the MCP server (e.g., CI/CD pipelines, automated orchestration, or machine-to-machine workflows). Do not use long-lived Bearer tokens — use API keys instead for interactive or long-running sessions.
141
+
117
142
  ```bash
118
- npx -y @octopusdeploy/mcp-server --server-url https://your-octopus.com --api-key YOUR_API_KEY
143
+ OCTOPUS_ACCESS_TOKEN=your-short-lived-token \
144
+ OCTOPUS_SERVER_URL=https://your-octopus.com \
145
+ npx -y @octopusdeploy/mcp-server
119
146
  ```
120
147
 
148
+ Full example configuration with an access token:
149
+ ```json
150
+ {
151
+ "mcpServers": {
152
+ "octopusdeploy": {
153
+ "type": "stdio",
154
+ "command": "npx",
155
+ "args": ["-y", "@octopusdeploy/mcp-server"],
156
+ "env": {
157
+ "OCTOPUS_SERVER_URL": "https://your-octopus.com",
158
+ "OCTOPUS_ACCESS_TOKEN": "YOUR_TOKEN"
159
+ }
160
+ }
161
+ }
162
+ }
163
+ ```
164
+
165
+ If both an API key and an access token are provided, the access token takes precedence. The active authentication method is recorded in the log file (configurable with `--log-file`) so operators can confirm which credential is in use.
166
+
121
167
  ### Configuration Options
122
168
 
123
169
  The Octopus MCP Server supports several command-line options to customize which tools are available.
@@ -143,47 +189,68 @@ Available toolsets:
143
189
  - **projects** - Project operations
144
190
  - **deployments** - Deployment operations
145
191
  - **releases** - Release management
192
+ - **runbooks** - Runbook discovery and execution
146
193
  - **tasks** - Task operations
147
194
  - **tenants** - Multi-tenancy operations
148
195
  - **kubernetes** - Kubernetes operations
149
196
  - **machines** - Deployment target operations
150
197
  - **certificates** - Certificate operations
151
198
  - **accounts** - Account operations
199
+ - **interruptions** - Manual intervention and approval operations
200
+ - **featureToggles** - Inspect and lightly adjust customer feature toggles
201
+ - **context** - Authenticated user and project context (current user, Git branches)
152
202
 
153
203
  #### Read-Only Mode
154
- The server runs in read-only mode by default for security. Most tools are read-only operations, but some tools can perform write operations (like creating releases and deployments).
204
+ The server runs with write tools enabled by default. Pass `--read-only` to disable all write tools and block POST/PUT/PATCH/DELETE through the `execute` backstop. Most curated tools are already read-only; only a small set perform writes.
155
205
 
156
- **Write-enabled tools:**
206
+ **Write-enabled tools (always-write):**
157
207
  - `create_release` - Create new releases
158
208
  - `deploy_release` - Deploy releases to environments and tenants
209
+ - `run_runbook` - Run a runbook against one or more environments (and optional tenants)
210
+ - `update_feature_toggle` - Adjust per-environment state and rollout percentages on an existing feature toggle
159
211
 
160
- To use write-enabled tools, you must explicitly disable read-only mode:
212
+ **Conditionally-writing tool:** `execute` is a structured REST backstop whose tier (read / write / delete) is determined by the HTTP method passed to it. See the [API Catalog & Backstop](#api-catalog--backstop) section for details.
213
+
214
+ Write tools are gated by an MCP elicitation prompt: clients that support elicitation will be asked to confirm before the call proceeds. Clients without elicitation support must pass `confirm: true` in the tool arguments — otherwise the tool aborts with an error. Set `OCTOPUS_SKIP_ELICITATION=true` to bypass the gate entirely (intended for unattended automation).
215
+
216
+ The server uses a three-tier read/write/delete classification, enforced server-side based on the HTTP method (the agent cannot bypass this by lying about intent):
217
+
218
+ - **read** — always allowed. GET requests through `execute`, plus all `find_*` / `get_*` / `list_*` tools.
219
+ - **write** — POST/PUT/PATCH through `execute` and the always-write tools above. Blocked when `--read-only` is set.
220
+ - **delete** — DELETE through `execute`. Requires `--allow-deletes` and is blocked when `--read-only` is set. A small set of catastrophic-delete paths (e.g. `DELETE /api/spaces/{id}`, `DELETE /api/users/{id}`) and API-key endpoints are on a hard sensitive denylist that ignores both flags.
161
221
 
162
222
  ```bash
163
- # Run in read-only mode (default) - write tools are disabled
223
+ # Default - write tools enabled (POST/PUT/PATCH)
164
224
  npx -y @octopusdeploy/mcp-server
165
225
 
166
- # Disable read-only mode to enable write operations
167
- npx -y @octopusdeploy/mcp-server --no-read-only
226
+ # Read-only mode - write/delete tools disabled
227
+ npx -y @octopusdeploy/mcp-server --read-only
228
+
229
+ # Additionally permit DELETE requests through the execute tool
230
+ npx -y @octopusdeploy/mcp-server --allow-deletes
168
231
  ```
169
232
 
170
- **Security Note:** When disabling read-only mode, ensure you use an API key with appropriate, least-privilege permissions. Write operations can create releases and trigger deployments in your Octopus instance.
233
+ **Security Note:** Use an API key with appropriate, least-privilege permissions write operations can create releases and trigger deployments in your Octopus instance. For production, consider passing `--read-only` unless you have a specific, controlled use case for writes. `--allow-deletes` is off by default; only enable it when the agent must issue DELETE requests through `execute`. If you pass `--allow-deletes` together with `--read-only`, the server prints a startup warning to stderr — DELETE requests remain blocked by the read-only gate.
171
234
 
172
235
  #### Complete Examples
173
236
 
237
+ All examples below assume `OCTOPUS_API_KEY` is set in the environment. The `--server-url` flag is shown for clarity but can also be provided via `OCTOPUS_SERVER_URL`.
238
+
174
239
  ```bash
175
240
  # Development setup with only core and project tools
176
- npx -y @octopusdeploy/mcp-server --toolsets core,projects --server-url https://your-octopus.com --api-key YOUR_API_KEY
241
+ npx -y @octopusdeploy/mcp-server --toolsets core,projects --server-url https://your-octopus.com
177
242
 
178
- # Full production setup with all tools (read-only by default)
179
- npx -y @octopusdeploy/mcp-server --toolsets all --server-url https://your-octopus.com --api-key YOUR_API_KEY
243
+ # Production setup with all tools and read-only enforcement
244
+ npx -y @octopusdeploy/mcp-server --toolsets all --read-only --server-url https://your-octopus.com
180
245
 
181
- # Development setup with write operations enabled
182
- npx -y @octopusdeploy/mcp-server --no-read-only --server-url https://your-octopus.com --api-key YOUR_API_KEY
246
+ # Default invocation - all tools and writes enabled
247
+ npx -y @octopusdeploy/mcp-server --server-url https://your-octopus.com
183
248
  ```
184
249
 
185
250
  #### Other command line arguments
186
251
 
252
+ * `--read-only` - Enable read-only mode: disable all curated write tools and block POST/PUT/PATCH/DELETE through `execute`. Writes are enabled by default; this flag turns them off. See [Read-Only Mode](#read-only-mode).
253
+ * `--allow-deletes` - Permit DELETE requests through the `execute` tool. Has no effect when `--read-only` is set. Default `false`.
187
254
  * `--log-level <level>` - Minimum log level (info, error)
188
255
  * `--log-file <path>` - Log file path or filename. If not specified, logs are written to console only
189
256
  * `-q, --quiet` - Disable file logging, only log errors to console
@@ -191,10 +258,65 @@ npx -y @octopusdeploy/mcp-server --no-read-only --server-url https://your-octopu
191
258
 
192
259
  ## 🔨 Tools
193
260
 
261
+ ### URL-Based Tools
262
+
263
+ **Quick start**: Paste Octopus URLs directly to investigate issues without manual ID extraction.
264
+
265
+ - `get_deployment_from_url`: Get deployment details from deployment URL (returns taskId for follow-up)
266
+ - `get_task_from_url`: Get task details and logs from task URL
267
+
268
+ **Deployment investigation workflow:**
269
+ ```
270
+ 1. get_deployment_from_url with deployment URL
271
+ → Returns deployment context + taskResourceUri + grepTaskLogHint
272
+
273
+ 2a. Fetch the structured activity tree via resources/read (or read_resource)
274
+ octopus://spaces/{spaceName}/tasks/{taskId}/details
275
+
276
+ 2b. Or call grep_task_log with the taskId to search the raw log without
277
+ fetching the full body:
278
+ grep_task_log({ spaceName, taskId, pattern: "error|fail", caseInsensitive: true })
279
+ ```
280
+
281
+ **Task investigation** (direct task URL):
282
+ ```
283
+ get_task_from_url with task URL
284
+ → Returns task details and logs immediately
285
+ ```
286
+
287
+ These tools eliminate manual ID extraction by:
288
+ - Parsing URLs automatically
289
+ - Resolving space IDs to space names
290
+ - Validating ID formats
291
+ - Providing clear error messages
292
+
293
+ **Example URLs:**
294
+ - Deployment: `https://your-octopus.com/app#/Spaces-1/projects/my-app/deployments/Deployments-123`
295
+ - Task: `https://your-octopus.com/app#/Spaces-1/tasks/ServerTasks-456`
296
+
297
+ See [Working with URLs](docs/working-with-urls.md) for detailed workflows, examples, and best practices.
298
+
194
299
  ### Core Tools
195
300
  - `list_spaces`: List all spaces in the Octopus Deploy instance
196
301
  - `list_environments`: List all environments in a given space
197
302
 
303
+ ### API Catalog & Backstop
304
+
305
+ These tools and resources let the agent reach Octopus REST endpoints that don't have a dedicated curated tool, with hard server-side gating between read, write, and delete operations.
306
+
307
+ - `grep_llms_txt`: Search the Octopus API catalog (`octopus://api/llms.txt`) with grep-style semantics (minimum supported Octopus version: `2026.2.3916`). The catalog body is large (typically 300+ KB) — call this rather than reading the resource body directly. Parameters mirror GNU grep (`pattern`, `caseInsensitive`, `invertMatch`, `fixedString`, `beforeContext`, `afterContext`, `maxCount`). Useful for discovering endpoints (`POST /releases`), enumerating delete endpoints (`DELETE `), or finding the body type for a write operation (`Body: Create.*Command`).
308
+ - `execute`: Structured REST backstop. Reaches any Octopus endpoint covered by the per-toolset path allowlist. The HTTP method is the authoritative read/write/delete classifier — never an `isWrite` flag the LLM can set. Method gating is hard-coded server-side:
309
+ - `GET` is always allowed (subject to the path allowlist + sensitive denylist).
310
+ - `POST`/`PUT`/`PATCH` are blocked when `--read-only` is set; otherwise they require user confirmation via elicitation.
311
+ - `DELETE` requires `--allow-deletes` (and is blocked when `--read-only` is set) plus a stronger "IRREVERSIBLE" elicitation message.
312
+ - The sensitive denylist (API-key endpoints, `DELETE /api/spaces/{id}`, `DELETE /api/users/{id}`) is enforced even with both flags on.
313
+ - The path allowlist is scoped per toolset — disabling a toolset (e.g. `certificates`) makes its paths unreachable through `execute`, even on GET.
314
+
315
+ Catalog data is also exposed as MCP Resources:
316
+
317
+ - `octopus://api/llms.txt` — markdown catalog of every Octopus REST endpoint (HTTP method, path, query params, request/response types). Requires Octopus Server `2026.2.3916` or later. 5-minute in-memory cache keyed on the configured server URL. **Prefer `grep_llms_txt` to reading the body directly.**
318
+ - `octopus://api/capabilities` — JSON describing the running session: server version, enabled toolsets, available tools (with their `minimumOctopusVersion`), and whether `--read-only` / `--allow-deletes` is on. Useful for the agent to discover what's reachable in this session.
319
+
198
320
  ### Projects
199
321
  - `list_projects`: List all projects in a given space
200
322
 
@@ -204,13 +326,27 @@ npx -y @octopusdeploy/mcp-server --no-read-only --server-url https://your-octopu
204
326
 
205
327
  ### Releases
206
328
  - `create_release`: Create a new release for a project
207
- - `find_releases`: Find releases in a space (can get a specific release by ID or list all releases)
208
- - `list_releases_for_project`: List all releases for a specific project
329
+ - `find_releases`: Find releases in a space (can get a specific release by ID, or list/filter releases by project)
330
+
331
+ Release detail is also available as an MCP Resource at `octopus://spaces/{spaceName}/releases/{releaseId}` — fetch via `resources/read` (or the `read_resource` backstop tool) to get the full release body, including release notes and selected packages.
332
+
333
+ ### Runbooks
334
+ - `find_runbooks`: Find runbooks in a project (can get a specific runbook by ID, or list/filter runbooks by partial name). Each summary includes the published snapshot ID, multi-tenancy mode, and environment scope so callers can pick valid targets before running.
335
+ - `run_runbook`: Run a runbook against one or more environments. Supports tenanted runs (by tenant name or tenant tag), prompted variables, guided failure mode, scheduled run windows, and step or machine inclusion/exclusion. Defaults to the runbook's published snapshot if `runbookSnapshotId` is omitted.
336
+
337
+ The full runbook body (including runtime policy fields) is available as an MCP Resource at `octopus://spaces/{spaceName}/runbooks/{runbookId}`.
209
338
 
210
339
  ### Tasks
211
- - `get_task_by_id`: Get details for a specific server task by its ID
212
- - `get_task_details`: Get detailed information for a specific server task
213
- - `get_task_raw`: Get raw details for a specific server task
340
+ Task data is primarily exposed as MCP Resources. Use `resources/read` (or the `read_resource` backstop tool) with one of:
341
+
342
+ - `octopus://spaces/{spaceName}/tasks/{taskId}` lightweight metadata (state, timing, completion flags)
343
+ - `octopus://spaces/{spaceName}/tasks/{taskId}/details` — full ServerTaskDetails (Progress, ActivityLogs tree, etc.)
344
+
345
+ For log search, use the `grep_task_log` tool rather than a `/log` resource:
346
+
347
+ - `grep_task_log`: Search a task's activity log without fetching the full body. Parameters mirror GNU grep (`pattern`, `caseInsensitive`, `invertMatch`, `fixedString`, `beforeContext`, `afterContext`, `maxCount`). Returns matching lines with 1-indexed `lineNumber`, optional before/after context arrays, and a `totalMatches` count across the whole log.
348
+
349
+ There is intentionally no `/log` resource: activity logs can be multi-megabyte, and an addressable resource would tempt callers to fetch the entire body when grep is almost always the right primitive.
214
350
 
215
351
  ### Tenants
216
352
  - `find_tenants`: Find tenants in a space (can get a specific tenant by ID or list/search tenants with filters)
@@ -229,8 +365,20 @@ npx -y @octopusdeploy/mcp-server --no-read-only --server-url https://your-octopu
229
365
  ### Accounts
230
366
  - `find_accounts`: Find accounts in a space (can get a specific account by ID or list/search accounts with filters)
231
367
 
368
+ ### Interruptions
369
+ - `find_interruptions`: Find pending or historical interruptions (manual interventions, approvals, guided-failure prompts) in a space, optionally filtered by task, project, environment, regarding document, responsibility, or pending state. Returns slim summaries; dereference the `octopus://spaces/{spaceName}/interruptions/{interruptionId}` resource for the full Form definition (control types, Markdown instructions, button options, submitted Form.Values).
370
+
371
+ ### Feature Toggles
372
+ - `find_feature_toggles`: List customer feature toggles in a project. Each summary includes per-environment state (`isEnabled`, `rolloutPercentage`, `clientRolloutPercentage`) plus a `resourceUri` so "where is X turned on" is answerable from the list response.
373
+ - `update_feature_toggle`: Adjust an existing toggle. Narrow surface — flip an environment on/off, change rollout percentages, or update the toggle-level description / default state. Internally fetches the current toggle, applies your patches in memory, and PUTs the merged body, so unmentioned environments and unmentioned fields are preserved. Patches that reference an environment not already configured on the toggle are rejected.
374
+
375
+ The full toggle body (description, tenants, segments, minimum versions) is available as an MCP Resource at `octopus://spaces/{spaceName}/projects/{projectId}/featuretoggles/{slug}`. Rollout group bodies are addressable at `octopus://spaces/{spaceName}/projects/{projectId}/rolloutgroups/{rolloutGroupId}` for read-only inspection.
376
+
377
+ **Out of scope (use the Octopus UI):** creating new feature toggles, deleting toggles, renaming or retagging, attaching/detaching rollout groups, tenant targeting, segments, minimum-version filters, and rollout-group / SDK client-identifier management.
378
+
232
379
  ### Additional Tools
233
380
  - `get_deployment_process`: Get deployment process by ID for projects or releases
381
+ - `get_variables`: Get all project variables and library variable set variables for a project (supports config-as-code projects via `gitRef`)
234
382
  - `get_branches`: Get Git branches for a version-controlled project (minimum supported version: `2021.2`)
235
383
  - `get_current_user`: Get information about the current authenticated user
236
384
 
@@ -244,16 +392,23 @@ The Octopus MCP Server includes both read and write operations. Important securi
244
392
  - Exercise caution when connecting to tools and models you do not fully trust
245
393
 
246
394
  ### Write Operations
247
- When read-only mode is disabled (`--no-read-only`), the following write operations are available:
395
+ By default, the following write operations are available:
248
396
  - **Creating releases**: Can create new releases for projects
249
397
  - **Deploying releases**: Can trigger deployments to environments (including production)
398
+ - **Running runbooks**: Can execute runbooks against environments and tenants
399
+ - **Updating feature toggles**: Can flip per-environment state and change rollout percentages on existing toggles
400
+ - **Arbitrary POST/PUT/PATCH via the `execute` backstop**: Subject to the per-toolset path allowlist and a sensitive denylist that's always-on.
401
+
402
+ Pass `--read-only` to disable all of the above. DELETE requests through `execute` require an additional `--allow-deletes` flag — a deliberate opt-in for irreversible operations — and remain blocked when `--read-only` is set.
250
403
 
251
404
  **Critical Security Measures:**
252
405
  1. **Least Privilege**: Use API keys with the minimum permissions needed for your use case
253
- 2. **Read-Only by Default**: The server defaults to read-only mode - you must explicitly opt-in to write operations
254
- 3. **Prompt Injection Risk**: Running agents in fully automated fashion could make you vulnerable to prompt-injection attacks
406
+ 2. **Opt In to Read-Only Mode**: Writes are enabled by default. For production, pass `--read-only` unless you have a specific, controlled use case for write operations. DELETE always requires the additional `--allow-deletes` opt-in.
407
+ 3. **Method gating is server-side and hard-coded**: The HTTP method passed to `execute` is the authoritative classifier. The agent cannot bypass the gate by misrepresenting what the call does — POST/PUT/PATCH/DELETE requests get tier-specific gating regardless of the prose in the request body.
408
+ 4. **Toolset filtering doubles as a kill switch**: Disabling a toolset removes both its curated tools and its paths from the `execute` allowlist.
409
+ 5. **Prompt Injection Risk**: Running agents in fully automated fashion could make you vulnerable to prompt-injection attacks
255
410
 
256
- **Recommendation**: For production environments, use read-only mode unless you have a specific, controlled use case for write operations.
411
+ **Recommendation**: For production environments, pass `--read-only` unless you have a specific, controlled use case for write operations. Leave `--allow-deletes` off unless you specifically need DELETE semantics through `execute`.
257
412
 
258
413
  ## ⚠️ Limitations
259
414
 
@@ -0,0 +1,4 @@
1
+ import { type ToolsetConfig } from "../types/toolConfig.js";
2
+ export declare function setActiveToolsetConfig(config: ToolsetConfig): void;
3
+ export declare function getActiveToolsetConfig(): ToolsetConfig;
4
+ //# sourceMappingURL=activeToolsetConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activeToolsetConfig.d.ts","sourceRoot":"","sources":["../../src/helpers/activeToolsetConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAc5D,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAElE;AAED,wBAAgB,sBAAsB,IAAI,aAAa,CAEtD"}
@@ -0,0 +1,18 @@
1
+ import {} from "../types/toolConfig.js";
2
+ /**
3
+ * Per-session ToolsetConfig holder.
4
+ *
5
+ * Resource handlers and the `execute` tool both register eagerly via
6
+ * side-effect imports, so they don't have access to the per-session config
7
+ * at module-eval time. registerResources writes the active config here at
8
+ * startup; the catalog/capabilities resource and execute tool read it on
9
+ * demand.
10
+ */
11
+ let activeConfig = {};
12
+ export function setActiveToolsetConfig(config) {
13
+ activeConfig = config;
14
+ }
15
+ export function getActiveToolsetConfig() {
16
+ return activeConfig;
17
+ }
18
+ //# sourceMappingURL=activeToolsetConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activeToolsetConfig.js","sourceRoot":"","sources":["../../src/helpers/activeToolsetConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,MAAM,wBAAwB,CAAC;AAE5D;;;;;;;;GAQG;AAEH,IAAI,YAAY,GAAkB,EAAE,CAAC;AAErC,MAAM,UAAU,sBAAsB,CAAC,MAAqB;IAC1D,YAAY,GAAG,MAAM,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,YAAY,CAAC;AACtB,CAAC"}
@@ -27,9 +27,12 @@ export declare const ENTITY_PREFIXES: {
27
27
  readonly environment: "Environments-";
28
28
  readonly tenant: "Tenants-";
29
29
  readonly release: "Releases-";
30
+ readonly runbook: "Runbooks-";
30
31
  readonly machine: "Machines-";
31
32
  readonly certificate: "Certificates-";
32
33
  readonly account: "Accounts-";
34
+ readonly deployment: "Deployments-";
33
35
  readonly deploymentProcess: "DeploymentProcesses-";
36
+ readonly interruption: "Interruptions-";
34
37
  };
35
38
  //# sourceMappingURL=errorHandling.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errorHandling.d.ts","sourceRoot":"","sources":["../../src/helpers/errorHandling.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,eAAe,EAAE,MAAM,GACtB,KAAK,IAAI,KAAK,CAIhB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE;IACP,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,KAAK,CAmDP;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,IAAI,CAeN;AAED;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;CAUlB,CAAC"}
1
+ {"version":3,"file":"errorHandling.d.ts","sourceRoot":"","sources":["../../src/helpers/errorHandling.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,eAAe,EAAE,MAAM,GACtB,KAAK,IAAI,KAAK,CAIhB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE;IACP,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,KAAK,CAmDP;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,IAAI,CAeN;AAED;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;CAalB,CAAC"}
@@ -29,7 +29,7 @@ export function handleOctopusApiError(error, context) {
29
29
  isErrorWithMessage(error, "401") ||
30
30
  isErrorWithMessage(error, "You must be logged in to request this resource") ||
31
31
  isErrorWithMessage(error, "provide a valid API key")) {
32
- throw new Error("Authentication failed. Ensure OCTOPUS_API_KEY environment variable is set with a valid API key. " +
32
+ throw new Error("Authentication failed. Ensure a valid API key (OCTOPUS_API_KEY) or access token (OCTOPUS_ACCESS_TOKEN) is provided. " +
33
33
  "You can generate an API key from your Octopus Deploy user profile.");
34
34
  }
35
35
  // Handle connection errors
@@ -64,9 +64,12 @@ export const ENTITY_PREFIXES = {
64
64
  environment: "Environments-",
65
65
  tenant: "Tenants-",
66
66
  release: "Releases-",
67
+ runbook: "Runbooks-",
67
68
  machine: "Machines-",
68
69
  certificate: "Certificates-",
69
70
  account: "Accounts-",
71
+ deployment: "Deployments-",
70
72
  deploymentProcess: "DeploymentProcesses-",
73
+ interruption: "Interruptions-",
71
74
  };
72
75
  //# sourceMappingURL=errorHandling.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errorHandling.js","sourceRoot":"","sources":["../../src/helpers/errorHandling.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errorHandling.js","sourceRoot":"","sources":["../../src/helpers/errorHandling.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,8 @@ import { type ClientConfiguration } from "@octopusdeploy/api-client";
2
2
  export interface ConfigurationOptions {
3
3
  instanceURL?: string;
4
4
  apiKey?: string;
5
+ accessToken?: string;
5
6
  }
7
+ export declare function getClientConfiguration(options?: ConfigurationOptions): ClientConfiguration;
6
8
  export declare function getClientConfigurationFromEnvironment(): ClientConfiguration;
7
9
  //# sourceMappingURL=getClientConfigurationFromEnvironment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getClientConfigurationFromEnvironment.d.ts","sourceRoot":"","sources":["../../src/helpers/getClientConfigurationFromEnvironment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAOrE,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA6BD,wBAAgB,qCAAqC,IAAI,mBAAmB,CAK3E"}
1
+ {"version":3,"file":"getClientConfigurationFromEnvironment.d.ts","sourceRoot":"","sources":["../../src/helpers/getClientConfigurationFromEnvironment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAQrE,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAaD,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CAiC9F;AAED,wBAAgB,qCAAqC,IAAI,mBAAmB,CAM3E"}
@@ -2,6 +2,7 @@ import {} from "@octopusdeploy/api-client";
2
2
  import { env } from "process";
3
3
  import { SEMVER_VERSION } from "../utils/version.js";
4
4
  import { getClientInfo } from "../utils/clientInfo.js";
5
+ import { logger } from "../utils/logger.js";
5
6
  const USER_AGENT_NAME = "octopus-mcp-server";
6
7
  function isEmpty(value) {
7
8
  return !value || value.trim().length === 0;
@@ -11,11 +12,25 @@ function constructUserAgent() {
11
12
  const userAgent = `${USER_AGENT_NAME}/${SEMVER_VERSION} (${clientInfo.name}/${clientInfo.version})`;
12
13
  return userAgent;
13
14
  }
14
- function getClientConfiguration(options = {}) {
15
- if (isEmpty(options.instanceURL) || isEmpty(options.apiKey)) {
16
- throw new Error("Octopus server URL and API key must be provided either via command line arguments (--server-url, --api-key) or environment variables (OCTOPUS_SERVER_URL, OCTOPUS_API_KEY).");
15
+ export function getClientConfiguration(options = {}) {
16
+ const hasApiKey = !isEmpty(options.apiKey);
17
+ const hasAccessToken = !isEmpty(options.accessToken);
18
+ if (isEmpty(options.instanceURL)) {
19
+ throw new Error("Octopus server URL must be provided either via command line argument (--server-url) or environment variable (OCTOPUS_SERVER_URL).");
20
+ }
21
+ if (!hasApiKey && !hasAccessToken) {
22
+ throw new Error("Octopus authentication must be provided via OCTOPUS_API_KEY or OCTOPUS_ACCESS_TOKEN environment variable.");
17
23
  }
18
24
  const userAgent = constructUserAgent();
25
+ if (hasAccessToken) {
26
+ logger.info("Authenticating with access token (Bearer)");
27
+ return {
28
+ userAgentApp: userAgent,
29
+ instanceURL: options.instanceURL,
30
+ accessToken: options.accessToken,
31
+ };
32
+ }
33
+ logger.info("Authenticating with API key");
19
34
  return {
20
35
  userAgentApp: userAgent,
21
36
  instanceURL: options.instanceURL,
@@ -25,7 +40,8 @@ function getClientConfiguration(options = {}) {
25
40
  export function getClientConfigurationFromEnvironment() {
26
41
  return getClientConfiguration({
27
42
  instanceURL: env["CLI_SERVER_URL"] || env["OCTOPUS_SERVER_URL"],
28
- apiKey: env["CLI_API_KEY"] || env["OCTOPUS_API_KEY"],
43
+ apiKey: env["OCTOPUS_API_KEY"],
44
+ accessToken: env["OCTOPUS_ACCESS_TOKEN"],
29
45
  });
30
46
  }
31
47
  //# sourceMappingURL=getClientConfigurationFromEnvironment.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getClientConfigurationFromEnvironment.js","sourceRoot":"","sources":["../../src/helpers/getClientConfigurationFromEnvironment.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAO7C,SAAS,OAAO,CAAC,KAAyB;IACxC,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,kBAAkB;IACzB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,MAAM,SAAS,GAAG,GAAG,eAAe,IAAI,cAAc,KAAK,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,OAAO,GAAG,CAAC;IAEpG,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,sBAAsB,CAAC,UAAgC,EAAE;IAChE,IAAI,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CACb,6KAA6K,CAC9K,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IAEvC,OAAO;QACL,YAAY,EAAE,SAAS;QACvB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qCAAqC;IACnD,OAAO,sBAAsB,CAAC;QAC5B,WAAW,EAAE,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,oBAAoB,CAAC;QAC/D,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,iBAAiB,CAAC;KACrD,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"getClientConfigurationFromEnvironment.js","sourceRoot":"","sources":["../../src/helpers/getClientConfigurationFromEnvironment.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAQ7C,SAAS,OAAO,CAAC,KAAyB;IACxC,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,kBAAkB;IACzB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,MAAM,SAAS,GAAG,GAAG,eAAe,IAAI,cAAc,KAAK,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,OAAO,GAAG,CAAC;IAEpG,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,UAAgC,EAAE;IACvE,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,cAAc,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAErD,IAAI,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CACb,mIAAmI,CACpI,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,SAAS,IAAI,CAAC,cAAc,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,2GAA2G,CAC5G,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IAEvC,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO;YACL,YAAY,EAAE,SAAS;YACvB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC3C,OAAO;QACL,YAAY,EAAE,SAAS;QACvB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qCAAqC;IACnD,OAAO,sBAAsB,CAAC;QAC5B,WAAW,EAAE,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,oBAAoB,CAAC;QAC/D,MAAM,EAAE,GAAG,CAAC,iBAAiB,CAAC;QAC9B,WAAW,EAAE,GAAG,CAAC,sBAAsB,CAAC;KACzC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * GNU-grep-shaped line search over a multi-line string. Pure function, used by
3
+ * grep_task_log (task activity logs) and grep_llms_txt (catalog markdown). Each
4
+ * line is tested independently; matching lines are emitted with optional
5
+ * symmetric context windows. Overlapping context between adjacent matches is
6
+ * NOT deduplicated — each match carries its own complete context window so the
7
+ * consumer can reason about each match in isolation. This is a deliberate
8
+ * departure from GNU grep's `--`-separated output but it is the right shape
9
+ * for a JSON tool response.
10
+ */
11
+ export interface GrepLinesParams {
12
+ pattern: string;
13
+ caseInsensitive?: boolean;
14
+ invertMatch?: boolean;
15
+ fixedString?: boolean;
16
+ beforeContext?: number;
17
+ afterContext?: number;
18
+ maxCount?: number;
19
+ }
20
+ export interface ContextLine {
21
+ lineNumber: number;
22
+ line: string;
23
+ }
24
+ export interface GrepMatch {
25
+ lineNumber: number;
26
+ line: string;
27
+ before?: ContextLine[];
28
+ after?: ContextLine[];
29
+ }
30
+ export interface GrepLinesResult {
31
+ totalLines: number;
32
+ totalMatches: number;
33
+ matches: GrepMatch[];
34
+ }
35
+ export declare const MAX_CONTEXT = 50;
36
+ export declare const MAX_COUNT_HARD_CAP = 500;
37
+ export declare function grepLines(rawText: string, params: GrepLinesParams): GrepLinesResult;
38
+ //# sourceMappingURL=grepLines.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grepLines.d.ts","sourceRoot":"","sources":["../../src/helpers/grepLines.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,eAAO,MAAM,WAAW,KAAK,CAAC;AAC9B,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAuBtC,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,eAAe,GACtB,eAAe,CAoDjB"}