harness-mcp-v2 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  An MCP (Model Context Protocol) server that gives AI agents full access to the Harness.io platform through 10 consolidated tools and 119+ resource types.
4
4
 
5
- [![CI](https://github.com/thisrohangupta/harness-poc-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/thisrohangupta/harness-poc-mcp/actions/workflows/ci.yml)
5
+ [![CI](https://github.com/thisrohangupta/harness-mcp-v2/actions/workflows/ci.yml/badge.svg)](https://github.com/thisrohangupta/harness-mcp-v2/actions/workflows/ci.yml)
6
6
 
7
7
  ## Why Use This MCP Server
8
8
 
@@ -13,7 +13,7 @@ This server is built differently:
13
13
  - **10 tools, 119+ resource types.** A registry-based dispatch system routes `harness_list`, `harness_get`, `harness_create`, etc. to any Harness resource — pipelines, services, environments, orgs, projects, feature flags, cost data, and more. The LLM picks from 10 tools instead of hundreds.
14
14
  - **Full platform coverage.** 25 toolsets spanning CI/CD, GitOps, Feature Flags, Cloud Cost Management, Security Testing, Chaos Engineering, Internal Developer Portal, Software Supply Chain, and more. Not just pipelines — the entire Harness platform.
15
15
  - **Multi-project workflows out of the box.** Agents discover organizations and projects dynamically — no hardcoded env vars needed. Ask "show failed executions across all projects" and the agent can navigate the full account hierarchy.
16
- - **24 prompt templates.** Pre-built prompts for common workflows: debug failed pipelines, review DORA metrics, triage vulnerabilities, optimize cloud costs, audit access control, plan feature flag rollouts, review pull requests, and more.
16
+ - **26 prompt templates.** Pre-built prompts for common workflows: build & deploy apps end-to-end, debug failed pipelines, review DORA metrics, triage vulnerabilities, optimize cloud costs, audit access control, plan feature flag rollouts, review pull requests, approve pending pipelines, and more.
17
17
  - **Works everywhere.** Stdio transport for local clients (Claude Desktop, Cursor, Windsurf), HTTP transport for remote/shared deployments, Docker and Kubernetes ready.
18
18
  - **Zero-config start.** Just provide a Harness API key. Account ID is auto-extracted from PAT tokens, org/project defaults are optional, and toolset filtering lets you expose only what you need.
19
19
  - **Extensible by design.** Adding a new Harness resource means adding a declarative data file — no new tool registration, no schema changes, no prompt updates.
@@ -25,17 +25,17 @@ This server is built differently:
25
25
  No install required — just run it:
26
26
 
27
27
  ```bash
28
- npx harness-poc-mcp-server
28
+ npx harness-mcp-v2
29
29
  ```
30
30
 
31
31
  That's it. Pass your Harness API key via environment variable or configure it in your AI client (see [Client Configuration](#client-configuration) below).
32
32
 
33
33
  ```bash
34
34
  # Stdio transport (default — for Claude Desktop, Cursor, Windsurf, etc.)
35
- HARNESS_API_KEY=pat.xxx npx harness-poc-mcp-server
35
+ HARNESS_API_KEY=pat.xxx npx harness-mcp-v2
36
36
 
37
37
  # HTTP transport (for remote/shared deployments)
38
- HARNESS_API_KEY=pat.xxx npx harness-poc-mcp-server http --port 8080
38
+ HARNESS_API_KEY=pat.xxx npx harness-mcp-v2 http --port 8080
39
39
  ```
40
40
 
41
41
  > **Note:** The account ID is auto-extracted from PAT tokens (`pat.<accountId>.<tokenId>.<secret>`), so `HARNESS_ACCOUNT_ID` is only needed for non-PAT API keys.
@@ -43,10 +43,10 @@ HARNESS_API_KEY=pat.xxx npx harness-poc-mcp-server http --port 8080
43
43
  ### Option 2: Global Install
44
44
 
45
45
  ```bash
46
- npm install -g harness-poc-mcp-server
46
+ npm install -g harness-mcp-v2
47
47
 
48
48
  # Then run directly
49
- harness-poc-mcp-server
49
+ harness-mcp-v2
50
50
  ```
51
51
 
52
52
  ### Option 3: Build from Source
@@ -54,8 +54,8 @@ harness-poc-mcp-server
54
54
  For development or customization:
55
55
 
56
56
  ```bash
57
- git clone https://github.com/thisrohangupta/harness-poc-mcp.git
58
- cd harness-poc-mcp
57
+ git clone https://github.com/thisrohangupta/harness-mcp-v2.git
58
+ cd harness-mcp-v2
59
59
  pnpm install
60
60
  pnpm build
61
61
 
@@ -68,7 +68,7 @@ pnpm inspect # Test with MCP Inspector
68
68
  ### CLI Usage
69
69
 
70
70
  ```bash
71
- harness-mcp-server [stdio|http] [--port <number>]
71
+ harness-mcp-v2 [stdio|http] [--port <number>]
72
72
 
73
73
  Options:
74
74
  --port <number> Port for HTTP transport (default: 3000, or PORT env var)
@@ -121,7 +121,7 @@ curl -X POST http://localhost:3000/mcp \
121
121
  "mcpServers": {
122
122
  "harness": {
123
123
  "command": "npx",
124
- "args": ["harness-poc-mcp-server"],
124
+ "args": ["harness-mcp-v2"],
125
125
  "env": {
126
126
  "HARNESS_API_KEY": "pat.xxx.xxx.xxx"
127
127
  }
@@ -136,14 +136,14 @@ curl -X POST http://localhost:3000/mcp \
136
136
  <summary>node (local install)</summary>
137
137
 
138
138
  ```bash
139
- npm install -g harness-poc-mcp-server
139
+ npm install -g harness-mcp-v2
140
140
  ```
141
141
 
142
142
  ```json
143
143
  {
144
144
  "mcpServers": {
145
145
  "harness": {
146
- "command": "harness-poc-mcp-server",
146
+ "command": "harness-mcp-v2",
147
147
  "env": {
148
148
  "HARNESS_API_KEY": "pat.xxx.xxx.xxx"
149
149
  }
@@ -160,7 +160,7 @@ npm install -g harness-poc-mcp-server
160
160
  <summary>npx (zero install)</summary>
161
161
 
162
162
  ```bash
163
- claude mcp add harness -- npx harness-poc-mcp-server
163
+ claude mcp add harness -- npx harness-mcp-v2
164
164
  ```
165
165
 
166
166
  </details>
@@ -169,8 +169,8 @@ claude mcp add harness -- npx harness-poc-mcp-server
169
169
  <summary>node (local install)</summary>
170
170
 
171
171
  ```bash
172
- npm install -g harness-poc-mcp-server
173
- claude mcp add harness -- harness-poc-mcp-server
172
+ npm install -g harness-mcp-v2
173
+ claude mcp add harness -- harness-mcp-v2
174
174
  ```
175
175
 
176
176
  </details>
@@ -187,7 +187,7 @@ Then set `HARNESS_API_KEY` in your environment or `.env` file.
187
187
  "mcpServers": {
188
188
  "harness": {
189
189
  "command": "npx",
190
- "args": ["harness-poc-mcp-server"],
190
+ "args": ["harness-mcp-v2"],
191
191
  "env": {
192
192
  "HARNESS_API_KEY": "pat.xxx.xxx.xxx"
193
193
  }
@@ -202,14 +202,14 @@ Then set `HARNESS_API_KEY` in your environment or `.env` file.
202
202
  <summary>node (local install)</summary>
203
203
 
204
204
  ```bash
205
- npm install -g harness-poc-mcp-server
205
+ npm install -g harness-mcp-v2
206
206
  ```
207
207
 
208
208
  ```json
209
209
  {
210
210
  "mcpServers": {
211
211
  "harness": {
212
- "command": "harness-poc-mcp-server",
212
+ "command": "harness-mcp-v2",
213
213
  "env": {
214
214
  "HARNESS_API_KEY": "pat.xxx.xxx.xxx"
215
215
  }
@@ -230,7 +230,7 @@ npm install -g harness-poc-mcp-server
230
230
  "mcpServers": {
231
231
  "harness": {
232
232
  "command": "npx",
233
- "args": ["harness-poc-mcp-server"],
233
+ "args": ["harness-mcp-v2"],
234
234
  "env": {
235
235
  "HARNESS_API_KEY": "pat.xxx.xxx.xxx"
236
236
  }
@@ -245,14 +245,14 @@ npm install -g harness-poc-mcp-server
245
245
  <summary>node (local install)</summary>
246
246
 
247
247
  ```bash
248
- npm install -g harness-poc-mcp-server
248
+ npm install -g harness-mcp-v2
249
249
  ```
250
250
 
251
251
  ```json
252
252
  {
253
253
  "mcpServers": {
254
254
  "harness": {
255
- "command": "harness-poc-mcp-server",
255
+ "command": "harness-mcp-v2",
256
256
  "env": {
257
257
  "HARNESS_API_KEY": "pat.xxx.xxx.xxx"
258
258
  }
@@ -271,7 +271,7 @@ Replace the command with the path to your built `index.js`:
271
271
  ```json
272
272
  {
273
273
  "command": "node",
274
- "args": ["/absolute/path/to/harness-poc-mcp/build/index.js", "stdio"]
274
+ "args": ["/absolute/path/to/harness-mcp-v2/build/index.js", "stdio"]
275
275
  }
276
276
  ```
277
277
 
@@ -296,7 +296,7 @@ Register the server in your Docker MCP Gateway configuration:
296
296
  "mcpServers": {
297
297
  "harness": {
298
298
  "command": "npx",
299
- "args": ["harness-poc-mcp-server"],
299
+ "args": ["harness-mcp-v2"],
300
300
  "env": {
301
301
  "HARNESS_API_KEY": "pat.xxx.xxx.xxx"
302
302
  }
@@ -314,7 +314,7 @@ Add the Harness MCP server to your [Portkey MCP Gateway](https://portkey.ai/feat
314
314
  "mcpServers": {
315
315
  "harness": {
316
316
  "command": "npx",
317
- "args": ["harness-poc-mcp-server"],
317
+ "args": ["harness-mcp-v2"],
318
318
  "env": {
319
319
  "HARNESS_API_KEY": "pat.xxx.xxx.xxx"
320
320
  }
@@ -332,7 +332,7 @@ mcp_servers:
332
332
  - name: harness
333
333
  command: npx
334
334
  args:
335
- - harness-poc-mcp-server
335
+ - harness-mcp-v2
336
336
  env:
337
337
  HARNESS_API_KEY: "pat.xxx.xxx.xxx"
338
338
  ```
@@ -343,7 +343,7 @@ The server works with [Envoy AI Gateway's MCP support](https://aigateway.envoypr
343
343
 
344
344
  ```bash
345
345
  # Start the server in HTTP mode
346
- HARNESS_API_KEY=pat.xxx.xxx.xxx npx harness-poc-mcp-server http --port 8080
346
+ HARNESS_API_KEY=pat.xxx.xxx.xxx npx harness-mcp-v2 http --port 8080
347
347
  ```
348
348
 
349
349
  Then configure Envoy to route to `http://localhost:8080/mcp` as an upstream MCP backend.
@@ -423,10 +423,10 @@ The server exposes 10 MCP tools. Every tool accepts `org_id` and `project_id` as
423
423
  | `harness_describe` | Discover available resource types, operations, and fields. No API call — returns local registry metadata. |
424
424
  | `harness_list` | List resources of a given type with filtering, search, and pagination. |
425
425
  | `harness_get` | Get a single resource by its identifier. |
426
- | `harness_create` | Create a new resource. Requires `confirmation: true`. |
427
- | `harness_update` | Update an existing resource. Requires `confirmation: true`. |
428
- | `harness_delete` | Delete a resource. Requires `confirmation: true`. Destructive. |
429
- | `harness_execute` | Execute an action on a resource (run pipeline, toggle flag, sync app). Requires `confirmation: true`. |
426
+ | `harness_create` | Create a new resource. Prompts for user confirmation via [elicitation](#elicitation). |
427
+ | `harness_update` | Update an existing resource. Prompts for user confirmation via [elicitation](#elicitation). |
428
+ | `harness_delete` | Delete a resource. Prompts for user confirmation via [elicitation](#elicitation). Destructive. |
429
+ | `harness_execute` | Execute an action on a resource (run pipeline, toggle flag, sync app). Prompts for user confirmation via [elicitation](#elicitation). |
430
430
  | `harness_search` | Search across multiple resource types in parallel with a single query. |
431
431
  | `harness_diagnose` | Aggregate execution details, pipeline YAML, and logs into a single diagnostic payload. |
432
432
  | `harness_status` | Get a real-time project health dashboard — recent executions, failure rates, and deep links. |
@@ -470,7 +470,6 @@ The server exposes 10 MCP tools. Every tool accepts `org_id` and `project_id` as
470
470
  "resource_type": "pipeline",
471
471
  "action": "run",
472
472
  "resource_id": "my-pipeline",
473
- "confirmation": true,
474
473
  "inputs": { "tag": "v1.2.3" }
475
474
  }
476
475
  ```
@@ -483,8 +482,7 @@ The server exposes 10 MCP tools. Every tool accepts `org_id` and `project_id` as
483
482
  "action": "toggle",
484
483
  "resource_id": "new_checkout_flow",
485
484
  "enable": true,
486
- "environment": "production",
487
- "confirmation": true
485
+ "environment": "production"
488
486
  }
489
487
  ```
490
488
 
@@ -511,8 +509,7 @@ The server exposes 10 MCP tools. Every tool accepts `org_id` and `project_id` as
511
509
  ```json
512
510
  {
513
511
  "resource_type": "connector",
514
- "body": { "connector": { "name": "My Docker Hub", "identifier": "my_docker", "type": "DockerRegistry" } },
515
- "confirmation": true
512
+ "body": { "connector": { "name": "My Docker Hub", "identifier": "my_docker", "type": "DockerRegistry" } }
516
513
  }
517
514
  ```
518
515
 
@@ -522,8 +519,7 @@ The server exposes 10 MCP tools. Every tool accepts `org_id` and `project_id` as
522
519
  {
523
520
  "resource_type": "trigger",
524
521
  "resource_id": "nightly-trigger",
525
- "pipeline_id": "my-pipeline",
526
- "confirmation": true
522
+ "pipeline_id": "my-pipeline"
527
523
  }
528
524
  ```
529
525
 
@@ -785,6 +781,7 @@ The server exposes 10 MCP tools. Every tool accepts `org_id` and `project_id` as
785
781
 
786
782
  | Prompt | Description | Parameters |
787
783
  |--------|-------------|------------|
784
+ | `build-deploy-app` | End-to-end CI/CD workflow: scan a git repo, generate CI pipeline (build & push Docker image), discover or generate K8s manifests, create CD pipeline, and deploy — with auto-retry on CI failures (up to 5 attempts) and CD failures (up to 3 attempts with user permission). On exhausted retries, provides Harness UI deep links to all created resources for manual investigation. | `repoUrl` (required), `imageName` (required), `projectId` (optional), `namespace` (optional) |
788
785
  | `debug-pipeline-failure` | Analyze a failed execution: gathers execution details, pipeline YAML, and logs, then provides root cause analysis and suggested fixes | `executionId` (required), `projectId` (optional) |
789
786
  | `create-pipeline` | Generate a new pipeline YAML from natural language requirements, reviewing existing resources for context | `description` (required), `projectId` (optional) |
790
787
  | `onboard-service` | Walk through onboarding a new service with environments and a deployment pipeline | `serviceName` (required), `projectId` (optional) |
@@ -1018,6 +1015,7 @@ src/
1018
1015
  pipeline-yaml.ts
1019
1016
  execution-summary.ts
1020
1017
  prompts/ # MCP prompt templates
1018
+ build-deploy-app.ts # DevOps: end-to-end build & deploy workflow
1021
1019
  debug-pipeline.ts # DevOps: debug failed executions
1022
1020
  create-pipeline.ts # DevOps: generate pipeline from requirements
1023
1021
  onboard-service.ts # DevOps: onboard new service
@@ -1042,10 +1040,12 @@ src/
1042
1040
  code-review.ts # Harness Code: PR code review
1043
1041
  pr-summary.ts # Harness Code: auto-generate PR summary
1044
1042
  branch-cleanup.ts # Harness Code: stale branch cleanup
1043
+ pending-approvals.ts # Approvals: find and act on pending approvals
1045
1044
  utils/
1046
1045
  cli.ts # CLI arg parsing (transport, port)
1047
1046
  errors.ts # Error normalization
1048
1047
  logger.ts # stderr-only logger
1048
+ progress.ts # MCP progress & logging notifications
1049
1049
  rate-limiter.ts # Client-side rate limiting
1050
1050
  deep-links.ts # Harness UI deep link builder
1051
1051
  response-formatter.ts # Consistent MCP response formatting
@@ -1060,10 +1060,32 @@ tests/
1060
1060
  registry.test.ts # Registry loading, filtering, dispatch tests
1061
1061
  ```
1062
1062
 
1063
+ ## Elicitation
1064
+
1065
+ Write tools (`harness_create`, `harness_update`, `harness_delete`, `harness_execute`) use [MCP elicitation](https://modelcontextprotocol.io/specification/2025-03-26/server/utilities/elicitation) to prompt the user for confirmation before making changes. This gives real human-in-the-loop approval — the user sees what's about to happen and accepts or declines.
1066
+
1067
+ **How it works:**
1068
+
1069
+ 1. The LLM calls a write tool (e.g. `harness_create` with a pipeline body)
1070
+ 2. The server sends an elicitation request to the client with a summary of the operation
1071
+ 3. The user sees the details and clicks **Accept** or **Decline**
1072
+ 4. If accepted, the operation proceeds. If declined, it's blocked and the LLM is told
1073
+
1074
+ **Client support:**
1075
+
1076
+ | Client | Elicitation Support |
1077
+ |--------|-------------------|
1078
+ | Cursor | Yes |
1079
+ | Claude Desktop | Not yet |
1080
+ | Windsurf | Not yet |
1081
+ | MCP Inspector | Yes |
1082
+
1083
+ For clients that don't support elicitation, the server proceeds directly — the LLM already chose to call the tool, so its intent is trusted. As more clients add elicitation support, users will automatically get the confirmation dialog without any server changes.
1084
+
1063
1085
  ## Safety
1064
1086
 
1065
1087
  - **Secrets are never exposed.** The `secret` resource type returns metadata only (name, type, scope) — secret values are never included in any response.
1066
- - **Write operations require confirmation.** `harness_create`, `harness_update`, `harness_delete`, and `harness_execute` all require `confirmation: true` before proceeding.
1088
+ - **Write operations prompt for confirmation.** `harness_create`, `harness_update`, `harness_delete`, and `harness_execute` use MCP elicitation to get user approval before proceeding (see [Elicitation](#elicitation)).
1067
1089
  - **Rate limiting.** The client enforces a 10 requests/second limit to avoid hitting Harness API rate limits.
1068
1090
  - **Retries with backoff.** Transient failures (HTTP 429, 5xx) are retried with exponential backoff and jitter.
1069
1091
  - **No stdout logging.** All logs go to stderr to avoid corrupting the stdio JSON-RPC transport.
@@ -1078,7 +1100,7 @@ tests/
1078
1100
  | HTTP `Invalid request` | Invalid JSON body or request body exceeded `HARNESS_MAX_BODY_SIZE_MB` | Validate JSON payload size/shape; increase `HARNESS_MAX_BODY_SIZE_MB` if needed |
1079
1101
  | `Unknown resource_type "..."` from tools | Resource type is misspelled or filtered out via `HARNESS_TOOLSETS` | Call `harness_describe` (with optional `search_term`) to discover valid types |
1080
1102
  | `Missing required field "... for path parameter ..."` | A project/org scoped call is missing identifiers | Set `HARNESS_DEFAULT_ORG_ID`/`HARNESS_DEFAULT_PROJECT_ID` or pass `org_id`/`project_id` per tool call |
1081
- | `Create/Update/Delete ... require confirmation=true` | Safety gate on mutating tools | Re-run with `confirmation: true` only after validating target/resource |
1103
+ | `Operation declined by user` | User declined the elicitation confirmation dialog | The user chose not to proceed verify the operation details and retry if intended |
1082
1104
  | `body.template_yaml (or body.yaml) is required` for template create/update | Template APIs expect full YAML payload | Provide full `template_yaml` string in `body`; for deletes, pass `version_label` to delete one version (omit to delete all versions) |
1083
1105
 
1084
1106
  ## License
package/build/index.js CHANGED
@@ -44,7 +44,7 @@ async function startStdio(config) {
44
44
  * when bound to localhost (validates Host header against allowed hostnames).
45
45
  */
46
46
  async function startHttp(config, port) {
47
- const host = "127.0.0.1";
47
+ const host = process.env.HOST || "127.0.0.1";
48
48
  const app = createMcpExpressApp({ host });
49
49
  const maxBodySize = config.HARNESS_MAX_BODY_SIZE_MB * 1024 * 1024;
50
50
  // Override the default express.json() limit to match our config
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.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 registerBuildDeployAppPrompt(server: McpServer): void;
3
+ //# sourceMappingURL=build-deploy-app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-deploy-app.d.ts","sourceRoot":"","sources":["../../src/prompts/build-deploy-app.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0LpE"}
@@ -0,0 +1,184 @@
1
+ import * as z from "zod/v4";
2
+ export function registerBuildDeployAppPrompt(server) {
3
+ server.prompt("build-deploy-app", "End-to-end workflow: scan a repo, generate CI/CD pipelines in Harness, build a Docker image, generate K8s manifests, and deploy", {
4
+ repoUrl: z.string().describe("Git repository URL (e.g. https://github.com/org/repo)"),
5
+ imageName: z.string().describe("Docker image name including registry (e.g. docker.io/myorg/myapp)"),
6
+ projectId: z.string().describe("Harness project identifier").optional(),
7
+ namespace: z.string().describe("Kubernetes namespace for deployment").optional(),
8
+ }, async ({ repoUrl, imageName, projectId, namespace }) => ({
9
+ messages: [{
10
+ role: "user",
11
+ content: {
12
+ type: "text",
13
+ text: `Build and deploy the application from "${repoUrl}" through Harness CI/CD.
14
+
15
+ Docker image: ${imageName}
16
+ ${projectId ? `Project: ${projectId}` : ""}
17
+ ${namespace ? `K8s namespace: ${namespace}` : "K8s namespace: default"}
18
+
19
+ IMPORTANT: Follow these steps IN ORDER. Complete each step before moving to the next.
20
+ Present the full plan and generated YAML for review before creating anything.
21
+
22
+ ---
23
+
24
+ ## Phase 1: Local Discovery (no MCP tools)
25
+
26
+ ### Step 0 — Clone & verify the repo
27
+ - Clone "${repoUrl}" locally (or git pull if already cloned)
28
+ - Run \`ls -la\` to inspect the project structure
29
+
30
+ ### Step 1 — Scan for Dockerfile
31
+ - Look for a Dockerfile (or Dockerfile.*) in the repo root and subdirectories
32
+ - If no Dockerfile exists: analyze the codebase (language, framework, dependencies) and generate an optimized multi-stage Dockerfile. Commit it to the repo.
33
+ - If a Dockerfile exists: read it and verify it follows best practices (multi-stage build, non-root user, .dockerignore)
34
+
35
+ ### Step 2 — Analyze the application
36
+ - Identify the language/framework, exposed ports, environment variables, and health check endpoints
37
+ - Note any databases or external services the app depends on
38
+ - This context is needed for K8s manifest generation in Phase 3
39
+
40
+ ### Step 3 — Scan for existing Kubernetes manifests
41
+ - Search the repo for existing K8s manifests: look in \`k8s/\`, \`kubernetes/\`, \`deploy/\`, \`manifests/\`, \`helm/\`, \`.k8s/\`, or any \`*.yaml\`/\`*.yml\` files containing \`apiVersion\` and \`kind: Deployment\`
42
+ - If manifests exist: note their paths — these will be referenced by the Harness service definition in Phase 3
43
+ - If no manifests exist: flag that we need to generate them in Phase 3
44
+
45
+ ---
46
+
47
+ ## Phase 2: CI Pipeline — Build & Push (MCP tools)
48
+
49
+ ### Step 4 — Check existing Harness resources
50
+ - Call harness_list with resource_type="connector"${projectId ? ` and project_id="${projectId}"` : ""} to find existing Docker registry and Git connectors
51
+ - Call harness_list with resource_type="service"${projectId ? ` and project_id="${projectId}"` : ""} to check if this service already exists
52
+ - Call harness_list with resource_type="environment"${projectId ? ` and project_id="${projectId}"` : ""} to see available environments
53
+ - Call harness_describe with resource_type="pipeline" to understand the pipeline schema
54
+
55
+ ### Step 5 — Ensure connectors exist
56
+ - If no Docker registry connector exists: generate connector YAML for DockerHub (or the registry in "${imageName}") and present it for review
57
+ - If no Git connector exists for "${repoUrl}": generate a Git connector YAML and present it for review
58
+ - Create any missing connectors using harness_create with resource_type="connector" (only after user confirmation)
59
+
60
+ ### Step 6 — Generate CI pipeline YAML
61
+ Generate a Harness CI pipeline that:
62
+ - Clones "${repoUrl}" using the Git connector
63
+ - Builds the Docker image from the Dockerfile found in Step 1
64
+ - Tags the image as "${imageName}:<+pipeline.sequenceId>"
65
+ - Pushes to the Docker registry using the Docker connector
66
+ - Includes a build test step if the repo has tests (e.g. npm test, go test, pytest)
67
+
68
+ Present the full pipeline YAML for review. Do NOT create it yet.
69
+
70
+ ### Step 7 — Create & execute CI pipeline (with auto-retry)
71
+ - After user confirms the YAML, create it using harness_create with resource_type="pipeline"
72
+ - Execute it using harness_execute with resource_type="pipeline"
73
+ - Monitor progress using harness_status — poll until the execution completes or fails
74
+
75
+ **CI FAILURE RETRY LOOP (up to 5 attempts):**
76
+ If the CI pipeline fails:
77
+ 1. Call harness_get to retrieve the full execution details and logs
78
+ 2. Analyze the failure — identify the root cause (build error, test failure, Dockerfile issue, dependency problem, etc.)
79
+ 3. Fix the issue locally:
80
+ - If it's a code/Dockerfile/config issue: edit the file in the repo, commit, and push the fix
81
+ - If it's a pipeline YAML issue: update the pipeline using harness_update with resource_type="pipeline"
82
+ - If it's a connector/credential issue: flag it to the user with a link to the connector in Harness
83
+ 4. Re-execute the pipeline using harness_execute
84
+ 5. Monitor again with harness_status
85
+ 6. Repeat this loop up to 5 total attempts
86
+
87
+ If still failing after 5 attempts:
88
+ - Summarize all 5 failure reasons and the fixes attempted
89
+ - Provide Harness UI deep links to the pipeline and latest execution
90
+ - Say: "The CI build has failed 5 times. You may need to manually investigate. Here are links to the resources in Harness:"
91
+ - List all created resource links (pipeline, connectors, etc.)
92
+
93
+ ---
94
+
95
+ ## Phase 3: CD Pipeline — K8s Manifests & Deploy (MCP tools + local)
96
+
97
+ ### Step 8 — Prepare Kubernetes manifests
98
+ **If manifests were found in Step 3:**
99
+ - Read and review the existing manifests
100
+ - Verify the image reference can be parameterized for Harness (e.g. \`${imageName}:<+artifact.tag>\`)
101
+ - Update the image field if needed, commit and push
102
+
103
+ **If no manifests were found in Step 3:**
104
+ - Generate K8s manifests based on the app analysis from Step 2:
105
+ - **Deployment**: with image "${imageName}:<+artifact.tag>", correct ports, resource requests/limits, liveness/readiness probes, and environment variables
106
+ - **Service**: ClusterIP or LoadBalancer matching the exposed ports
107
+ - **ConfigMap/Secret**: for any environment variables the app needs (secret values as placeholders only)
108
+ - Save the manifests in a \`k8s/\` directory in the repo
109
+ - Commit and push the manifests to the repo
110
+ - Present all manifests for review
111
+
112
+ ### Step 9 — Create Harness service & environment
113
+ - Create (or update) a Harness service definition that references the K8s manifests from the repo:
114
+ - Service type: Kubernetes
115
+ - Manifest source: the Git connector from Step 5 pointing to the manifest path in the repo
116
+ - Artifact source: the Docker registry connector pointing to "${imageName}"
117
+ - Ensure a target environment exists (or create one) for the ${namespace || "default"} namespace
118
+ - Present the service and environment YAML for review before creating
119
+
120
+ ### Step 10 — Generate CD pipeline YAML
121
+ Generate a Harness CD pipeline that:
122
+ - References the service and environment from Step 9
123
+ - Uses a Kubernetes deployment type
124
+ - Uses a Rolling deployment strategy
125
+ - Includes infrastructure definition targeting the ${namespace || "default"} namespace
126
+ - Includes a Verify step or health check after deployment
127
+
128
+ Present the full pipeline YAML for review. Do NOT create it yet.
129
+
130
+ ### Step 11 — Create & execute CD pipeline (with auto-retry)
131
+ - After user confirms, create the CD pipeline using harness_create with resource_type="pipeline"
132
+ - Execute it using harness_execute with resource_type="pipeline"
133
+ - Monitor with harness_status — poll until the execution completes or fails
134
+
135
+ **CD FAILURE RETRY LOOP (up to 3 attempts):**
136
+ If the CD pipeline fails:
137
+ 1. Call harness_get to retrieve execution details and deployment logs
138
+ 2. Analyze the failure — identify root cause (manifest error, image pull failure, resource quota, RBAC, health check timeout, etc.)
139
+ 3. Determine the fix:
140
+ - If it's a manifest issue: fix the K8s manifests in the repo, commit and push
141
+ - If it's a pipeline/infrastructure issue: update the pipeline using harness_update
142
+ - If it's a Harness configuration issue (connector, delegate, permissions): explain the issue clearly
143
+ 4. Ask the user for permission to retry: "Deployment failed due to [reason]. I've applied [fix]. May I retry?"
144
+ 5. On approval, re-execute the pipeline and monitor again
145
+ 6. Repeat up to 3 total attempts
146
+
147
+ If still failing after 3 attempts:
148
+ - Summarize all failure reasons and fixes attempted
149
+ - Provide Harness UI deep links to ALL created resources:
150
+ - CI pipeline + latest execution
151
+ - CD pipeline + latest execution
152
+ - Service definition
153
+ - Environment
154
+ - Connectors
155
+ - Say: "The deployment has failed 3 times. You may need to manually update some configuration in Harness. Here are links to all the resources that were created:"
156
+ - List every resource with its Harness UI link
157
+ - Say: "Once you've resolved the issue in Harness, you can re-run this workflow to try again."
158
+
159
+ ---
160
+
161
+ ### Step 12 — Success: Verify & report
162
+ - Confirm the deployment succeeded via harness_status
163
+ - Call harness_get to retrieve final execution details
164
+ - Display a summary:
165
+ - CI: execution status, image tag pushed, build duration
166
+ - CD: execution status, deployment details, namespace
167
+ - Links: Harness UI links to both pipelines, service, and environment
168
+ - App URL: if determinable from the K8s service (LoadBalancer IP/hostname)
169
+
170
+ ---
171
+
172
+ CRITICAL RULES:
173
+ - Do NOT create any resource (connector, pipeline, service) without showing the YAML and getting user confirmation first
174
+ - Do NOT skip steps — complete each one before proceeding
175
+ - On CI failure: auto-retry up to 5 times, fixing issues between each attempt
176
+ - On CD failure: analyze, fix, ask permission, retry up to 3 times
177
+ - After exhausting retries: provide Harness UI deep links to all created resources so the user can investigate manually
178
+ - Use existing connectors/services/environments when available — do not duplicate them
179
+ - Always reference existing K8s manifests from the repo when available — only generate new ones if none exist`,
180
+ },
181
+ }],
182
+ }));
183
+ }
184
+ //# sourceMappingURL=build-deploy-app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-deploy-app.js","sourceRoot":"","sources":["../../src/prompts/build-deploy-app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAG5B,MAAM,UAAU,4BAA4B,CAAC,MAAiB;IAC5D,MAAM,CAAC,MAAM,CACX,kBAAkB,EAClB,iIAAiI,EACjI;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uDAAuD,CAAC;QACrF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mEAAmE,CAAC;QACnG,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAC,QAAQ,EAAE;QACvE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC,CAAC,QAAQ,EAAE;KACjF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;QACvD,QAAQ,EAAE,CAAC;gBACT,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,0CAA0C,OAAO;;gBAEjD,SAAS;EACvB,SAAS,CAAC,CAAC,CAAC,YAAY,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE;EACxC,SAAS,CAAC,CAAC,CAAC,kBAAkB,SAAS,EAAE,CAAC,CAAC,CAAC,wBAAwB;;;;;;;;;;WAU3D,OAAO;;;;;;;;;;;;;;;;;;;;;;;oDAuBkC,SAAS,CAAC,CAAC,CAAC,oBAAoB,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE;kDACnD,SAAS,CAAC,CAAC,CAAC,oBAAoB,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE;sDAC7C,SAAS,CAAC,CAAC,CAAC,oBAAoB,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE;;;;uGAIA,SAAS;oCAC5E,OAAO;;;;;YAK/B,OAAO;;uBAEI,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wEAoCwC,SAAS;;;;;kCAK/C,SAAS;;;;;;;;;;;kEAWuB,SAAS;+DACZ,SAAS,IAAI,SAAS;;;;;;;;qDAQhC,SAAS,IAAI,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8GAsDmC;iBACrG;aACF,CAAC;KACH,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -26,7 +26,7 @@ Steps:
26
26
  6. **Safety gates**: Identify metrics or health checks between each phase
27
27
  7. **Rollback plan**: Define conditions that trigger automatic rollback
28
28
 
29
- Present the rollout plan for review. Use harness_execute with resource_type="feature_flag", action="toggle" to execute each phase only after confirmation.`,
29
+ Present the rollout plan for review. Use harness_execute with resource_type="feature_flag", action="toggle" to execute each phase after user approval.`,
30
30
  },
31
31
  }],
32
32
  };
@@ -1 +1 @@
1
- {"version":3,"file":"feature-flag-rollout.js","sourceRoot":"","sources":["../../src/prompts/feature-flag-rollout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAG5B,MAAM,UAAU,gCAAgC,CAAC,MAAiB;IAChE,MAAM,CAAC,MAAM,CACX,sBAAsB,EACtB,yEAAyE,EACzE;QACE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;QAC1E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,QAAQ,EAAE;KAChE,EACD,KAAK,EAAE,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE,EAAE;QACtC,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC,iBAAiB,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,OAAO;YACL,QAAQ,EAAE,CAAC;oBACT,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,gDAAgD,cAAc;;;4FAGY,cAAc,IAAI,aAAa;kFACzC,aAAa;+EAChB,aAAa;;;;;;;;;;;2JAW+D;qBAChJ;iBACF,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"feature-flag-rollout.js","sourceRoot":"","sources":["../../src/prompts/feature-flag-rollout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAG5B,MAAM,UAAU,gCAAgC,CAAC,MAAiB;IAChE,MAAM,CAAC,MAAM,CACX,sBAAsB,EACtB,yEAAyE,EACzE;QACE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;QAC1E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,QAAQ,EAAE;KAChE,EACD,KAAK,EAAE,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE,EAAE;QACtC,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC,iBAAiB,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,OAAO;YACL,QAAQ,EAAE,CAAC;oBACT,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,gDAAgD,cAAc;;;4FAGY,cAAc,IAAI,aAAa;kFACzC,aAAa;+EAChB,aAAa;;;;;;;;;;;uJAW2D;qBAC5I;iBACF,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAsCzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqC1D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAyCzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwC1D"}
@@ -28,6 +28,8 @@ import { registerPrSummaryPrompt } from "./pr-summary.js";
28
28
  import { registerBranchCleanupPrompt } from "./branch-cleanup.js";
29
29
  // Approval prompts
30
30
  import { registerPendingApprovalsPrompt } from "./pending-approvals.js";
31
+ // Deployment workflow prompts
32
+ import { registerBuildDeployAppPrompt } from "./build-deploy-app.js";
31
33
  export function registerAllPrompts(server) {
32
34
  // Existing prompts
33
35
  registerDebugPipelinePrompt(server);
@@ -60,5 +62,7 @@ export function registerAllPrompts(server) {
60
62
  registerBranchCleanupPrompt(server);
61
63
  // Approvals
62
64
  registerPendingApprovalsPrompt(server);
65
+ // Deployment workflows
66
+ registerBuildDeployAppPrompt(server);
63
67
  }
64
68
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"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"}
@@ -27,7 +27,7 @@ For each pending approval, show:
27
27
  - A deep link to the execution in Harness
28
28
 
29
29
  **Step 4: Offer to take action**
30
- Ask me if I want to approve or reject any of the pending approvals. If I choose to act, use harness_execute with resource_type="approval_instance", action="approve" (or "reject"), approval_id=<id>, and confirmation=true.
30
+ Ask me if I want to approve or reject any of the pending approvals. If I choose to act, use harness_execute with resource_type="approval_instance", action="approve" (or "reject"), approval_id=<id>.
31
31
 
32
32
  If no executions are waiting for approval, let me know the project is clear.`,
33
33
  },
@@ -1 +1 @@
1
- {"version":3,"file":"harness-create.d.ts","sourceRoot":"","sources":["../../src/tools/harness-create.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAIjE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAyBrG"}
1
+ {"version":3,"file":"harness-create.d.ts","sourceRoot":"","sources":["../../src/tools/harness-create.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAKjE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA6BrG"}
@@ -1,17 +1,22 @@
1
1
  import * as z from "zod/v4";
2
2
  import { jsonResult, errorResult } from "../utils/response-formatter.js";
3
3
  import { isUserError, toMcpError } from "../utils/errors.js";
4
+ import { confirmViaElicitation } from "../utils/elicitation.js";
4
5
  export function registerCreateTool(server, registry, client) {
5
- server.tool("harness_create", "Create a new Harness resource. Requires confirmation=true to proceed. For pipelines, templates, and triggers — read the schema resource first (e.g. schema:///pipeline) to understand the required body format.", {
6
+ server.tool("harness_create", "Create a new Harness resource. For pipelines, templates, and triggers — read the schema resource first (e.g. schema:///pipeline) to understand the required body format.", {
6
7
  resource_type: z.string().describe("The type of resource to create (e.g. pipeline, service, environment, connector, trigger)"),
7
8
  body: z.record(z.string(), z.unknown()).describe("The resource definition body (varies by resource type — typically the YAML or JSON spec)"),
8
- confirmation: z.boolean().describe("Must be true to confirm the create operation").default(false),
9
9
  org_id: z.string().describe("Organization identifier (overrides default)").optional(),
10
10
  project_id: z.string().describe("Project identifier (overrides default)").optional(),
11
11
  }, async (args) => {
12
12
  try {
13
- if (!args.confirmation) {
14
- return errorResult("Create operations require confirmation=true. Set confirmation to true to proceed.");
13
+ const elicit = await confirmViaElicitation({
14
+ server,
15
+ toolName: "harness_create",
16
+ message: `Create ${args.resource_type}?\n\n${JSON.stringify(args.body, null, 2)}`,
17
+ });
18
+ if (!elicit.proceed) {
19
+ return errorResult(`Operation ${elicit.reason} by user.`);
15
20
  }
16
21
  const result = await registry.dispatch(client, args.resource_type, "create", args);
17
22
  return jsonResult(result);
@@ -1 +1 @@
1
- {"version":3,"file":"harness-create.js","sourceRoot":"","sources":["../../src/tools/harness-create.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAI5B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE7D,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,QAAkB,EAAE,MAAqB;IAC7F,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,iNAAiN,EACjN;QACE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0FAA0F,CAAC;QAC9H,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,0FAA0F,CAAC;QAC5I,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;QACjG,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAAC,QAAQ,EAAE;QACrF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC,CAAC,QAAQ,EAAE;KACrF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;gBACvB,OAAO,WAAW,CAAC,mFAAmF,CAAC,CAAC;YAC1G,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,IAA+B,CAAC,CAAC;YAC9G,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,WAAW,CAAC,GAAG,CAAC;gBAAE,OAAO,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACtD,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"harness-create.js","sourceRoot":"","sources":["../../src/tools/harness-create.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAI5B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,QAAkB,EAAE,MAAqB;IAC7F,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,0KAA0K,EAC1K;QACE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0FAA0F,CAAC;QAC9H,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,0FAA0F,CAAC;QAC5I,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAAC,QAAQ,EAAE;QACrF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC,CAAC,QAAQ,EAAE;KACrF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC;gBACzC,MAAM;gBACN,QAAQ,EAAE,gBAAgB;gBAC1B,OAAO,EAAE,UAAU,IAAI,CAAC,aAAa,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;aAClF,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO,WAAW,CAAC,aAAa,MAAM,CAAC,MAAM,WAAW,CAAC,CAAC;YAC5D,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,IAA+B,CAAC,CAAC;YAC9G,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,WAAW,CAAC,GAAG,CAAC;gBAAE,OAAO,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACtD,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"harness-delete.d.ts","sourceRoot":"","sources":["../../src/tools/harness-delete.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAIjE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAiCrG"}
1
+ {"version":3,"file":"harness-delete.d.ts","sourceRoot":"","sources":["../../src/tools/harness-delete.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAKjE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAqCrG"}
@@ -1,19 +1,24 @@
1
1
  import * as z from "zod/v4";
2
2
  import { jsonResult, errorResult } from "../utils/response-formatter.js";
3
3
  import { isUserError, toMcpError } from "../utils/errors.js";
4
+ import { confirmViaElicitation } from "../utils/elicitation.js";
4
5
  export function registerDeleteTool(server, registry, client) {
5
- server.tool("harness_delete", "Delete a Harness resource. Requires confirmation=true to proceed. This is destructive and cannot be undone.", {
6
+ server.tool("harness_delete", "Delete a Harness resource. This is destructive and cannot be undone.", {
6
7
  resource_type: z.string().describe("The type of resource to delete (e.g. pipeline, trigger, connector)"),
7
8
  resource_id: z.string().describe("The identifier of the resource to delete"),
8
- confirmation: z.boolean().describe("Must be true to confirm the delete operation — this is destructive").default(false),
9
9
  org_id: z.string().describe("Organization identifier (overrides default)").optional(),
10
10
  project_id: z.string().describe("Project identifier (overrides default)").optional(),
11
11
  pipeline_id: z.string().describe("Pipeline ID (for trigger deletes)").optional(),
12
12
  environment_id: z.string().describe("Environment ID (for infrastructure deletes)").optional(),
13
13
  }, async (args) => {
14
14
  try {
15
- if (!args.confirmation) {
16
- return errorResult("Delete operations require confirmation=true. This is destructive and cannot be undone.");
15
+ const elicit = await confirmViaElicitation({
16
+ server,
17
+ toolName: "harness_delete",
18
+ message: `Delete ${args.resource_type} "${args.resource_id}"?\n\nThis is destructive and cannot be undone.`,
19
+ });
20
+ if (!elicit.proceed) {
21
+ return errorResult(`Operation ${elicit.reason} by user.`);
17
22
  }
18
23
  const def = registry.getResource(args.resource_type);
19
24
  const input = { ...args };
@@ -1 +1 @@
1
- {"version":3,"file":"harness-delete.js","sourceRoot":"","sources":["../../src/tools/harness-delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAI5B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE7D,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,QAAkB,EAAE,MAAqB;IAC7F,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,6GAA6G,EAC7G;QACE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;QACxG,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;QAC5E,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;QACvH,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAAC,QAAQ,EAAE;QACrF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC,CAAC,QAAQ,EAAE;QACpF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC,CAAC,QAAQ,EAAE;QAChF,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAAC,QAAQ,EAAE;KAC9F,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;gBACvB,OAAO,WAAW,CAAC,wFAAwF,CAAC,CAAC;YAC/G,CAAC;YAED,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACrD,MAAM,KAAK,GAA4B,EAAE,GAAG,IAAI,EAAE,CAAC;YACnD,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACxD,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC;YACpD,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YACpF,OAAO,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7K,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,WAAW,CAAC,GAAG,CAAC;gBAAE,OAAO,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACtD,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"harness-delete.js","sourceRoot":"","sources":["../../src/tools/harness-delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAI5B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,QAAkB,EAAE,MAAqB;IAC7F,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,sEAAsE,EACtE;QACE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;QACxG,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;QAC5E,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAAC,QAAQ,EAAE;QACrF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC,CAAC,QAAQ,EAAE;QACpF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC,CAAC,QAAQ,EAAE;QAChF,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAAC,QAAQ,EAAE;KAC9F,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC;gBACzC,MAAM;gBACN,QAAQ,EAAE,gBAAgB;gBAC1B,OAAO,EAAE,UAAU,IAAI,CAAC,aAAa,KAAK,IAAI,CAAC,WAAW,iDAAiD;aAC5G,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO,WAAW,CAAC,aAAa,MAAM,CAAC,MAAM,WAAW,CAAC,CAAC;YAC5D,CAAC;YAED,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACrD,MAAM,KAAK,GAA4B,EAAE,GAAG,IAAI,EAAE,CAAC;YACnD,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACxD,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC;YACpD,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YACpF,OAAO,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7K,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,WAAW,CAAC,GAAG,CAAC;gBAAE,OAAO,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACtD,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"harness-execute.d.ts","sourceRoot":"","sources":["../../src/tools/harness-execute.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAIjE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA4DtG"}
1
+ {"version":3,"file":"harness-execute.d.ts","sourceRoot":"","sources":["../../src/tools/harness-execute.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAKjE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAsDtG"}
@@ -1,12 +1,12 @@
1
1
  import * as z from "zod/v4";
2
2
  import { jsonResult, errorResult } from "../utils/response-formatter.js";
3
3
  import { isUserError, toMcpError } from "../utils/errors.js";
4
+ import { confirmViaElicitation } from "../utils/elicitation.js";
4
5
  export function registerExecuteTool(server, registry, client) {
5
6
  server.tool("harness_execute", "Execute an action on a Harness resource: run/retry/interrupt pipelines, toggle feature flags, test connectors, sync GitOps apps, run chaos experiments.", {
6
7
  resource_type: z.string().describe("The resource type (e.g. pipeline, execution, feature_flag, connector, gitops_application, chaos_experiment)"),
7
8
  action: z.string().describe("The action to execute (e.g. run, retry, interrupt, toggle, test_connection, sync)"),
8
9
  resource_id: z.string().describe("The primary identifier of the resource").optional(),
9
- confirmation: z.boolean().describe("Must be true to confirm execution").default(false),
10
10
  org_id: z.string().describe("Organization identifier (overrides default)").optional(),
11
11
  project_id: z.string().describe("Project identifier (overrides default)").optional(),
12
12
  // Dynamic fields for various actions
@@ -28,16 +28,13 @@ export function registerExecuteTool(server, registry, client) {
28
28
  body: z.record(z.string(), z.unknown()).describe("Additional body payload for the action").optional(),
29
29
  }, async (args) => {
30
30
  try {
31
- if (!args.confirmation) {
32
- // Show available actions for the resource type
33
- const actions = registry.getExecuteActions(args.resource_type);
34
- if (!actions) {
35
- return errorResult(`Resource "${args.resource_type}" has no execute actions.`);
36
- }
37
- const actionList = Object.entries(actions)
38
- .map(([name, spec]) => ` - ${name}: ${spec.actionDescription}`)
39
- .join("\n");
40
- return errorResult(`Execute operations require confirmation=true.\n\nAvailable actions for "${args.resource_type}":\n${actionList}`);
31
+ const elicit = await confirmViaElicitation({
32
+ server,
33
+ toolName: "harness_execute",
34
+ message: `Execute "${args.action}" on ${args.resource_type}${args.resource_id ? ` "${args.resource_id}"` : ""}?`,
35
+ });
36
+ if (!elicit.proceed) {
37
+ return errorResult(`Operation ${elicit.reason} by user.`);
41
38
  }
42
39
  // Map resource_id to the primary identifier field
43
40
  const def = registry.getResource(args.resource_type);
@@ -1 +1 @@
1
- {"version":3,"file":"harness-execute.js","sourceRoot":"","sources":["../../src/tools/harness-execute.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"harness-execute.js","sourceRoot":"","sources":["../../src/tools/harness-execute.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"harness-update.d.ts","sourceRoot":"","sources":["../../src/tools/harness-update.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAIjE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAwCrG"}
1
+ {"version":3,"file":"harness-update.d.ts","sourceRoot":"","sources":["../../src/tools/harness-update.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAKjE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA4CrG"}
@@ -1,20 +1,25 @@
1
1
  import * as z from "zod/v4";
2
2
  import { jsonResult, errorResult } from "../utils/response-formatter.js";
3
3
  import { isUserError, toMcpError } from "../utils/errors.js";
4
+ import { confirmViaElicitation } from "../utils/elicitation.js";
4
5
  export function registerUpdateTool(server, registry, client) {
5
- server.tool("harness_update", "Update an existing Harness resource. Requires confirmation=true to proceed. Response includes openInHarness link to the updated resource when applicable (e.g. pipeline, service).", {
6
+ server.tool("harness_update", "Update an existing Harness resource. Response includes openInHarness link to the updated resource when applicable (e.g. pipeline, service).", {
6
7
  resource_type: z.string().describe("The type of resource to update (e.g. pipeline, service, environment, connector, trigger)"),
7
8
  resource_id: z.string().describe("The identifier of the resource to update"),
8
9
  body: z.record(z.string(), z.unknown()).describe("The updated resource definition body"),
9
- confirmation: z.boolean().describe("Must be true to confirm the update operation").default(false),
10
10
  org_id: z.string().describe("Organization identifier (overrides default)").optional(),
11
11
  project_id: z.string().describe("Project identifier (overrides default)").optional(),
12
12
  pipeline_id: z.string().describe("Pipeline ID (for trigger updates)").optional(),
13
13
  version_label: z.string().describe("Template version label (for template updates; defaults to body.version_label or v1)").optional(),
14
14
  }, async (args) => {
15
15
  try {
16
- if (!args.confirmation) {
17
- return errorResult("Update operations require confirmation=true. Set confirmation to true to proceed.");
16
+ const elicit = await confirmViaElicitation({
17
+ server,
18
+ toolName: "harness_update",
19
+ message: `Update ${args.resource_type} "${args.resource_id}"?\n\n${JSON.stringify(args.body, null, 2)}`,
20
+ });
21
+ if (!elicit.proceed) {
22
+ return errorResult(`Operation ${elicit.reason} by user.`);
18
23
  }
19
24
  const def = registry.getResource(args.resource_type);
20
25
  const input = { ...args };
@@ -1 +1 @@
1
- {"version":3,"file":"harness-update.js","sourceRoot":"","sources":["../../src/tools/harness-update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAI5B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE7D,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,QAAkB,EAAE,MAAqB;IAC7F,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,oLAAoL,EACpL;QACE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0FAA0F,CAAC;QAC9H,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;QAC5E,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,sCAAsC,CAAC;QACxF,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;QACjG,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAAC,QAAQ,EAAE;QACrF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC,CAAC,QAAQ,EAAE;QACpF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC,CAAC,QAAQ,EAAE;QAChF,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qFAAqF,CAAC,CAAC,QAAQ,EAAE;KACrI,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;gBACvB,OAAO,WAAW,CAAC,mFAAmF,CAAC,CAAC;YAC1G,CAAC;YAED,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACrD,MAAM,KAAK,GAA4B,EAAE,GAAG,IAAI,EAAE,CAAC;YACnD,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACxD,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC;YACpD,CAAC;YACD,IAAI,IAAI,CAAC,aAAa;gBAAE,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;iBAC5D,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,eAAe,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACpF,KAAK,CAAC,aAAa,GAAI,IAAI,CAAC,IAAgC,CAAC,aAAa,CAAC;YAC7E,CAAC;iBAAM,IAAI,IAAI,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;gBAC7C,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;YAC7B,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YACpF,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,WAAW,CAAC,GAAG,CAAC;gBAAE,OAAO,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACtD,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"harness-update.js","sourceRoot":"","sources":["../../src/tools/harness-update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ export interface ElicitationResult {
4
+ /** Whether the operation should proceed. */
5
+ proceed: boolean;
6
+ /** Why the operation was stopped, if applicable. */
7
+ reason?: "declined" | "cancelled";
8
+ }
9
+ /**
10
+ * Check whether the connected client advertises form elicitation support.
11
+ */
12
+ export declare function clientSupportsElicitation(server: Server): boolean;
13
+ /**
14
+ * Prompt the user to confirm a write operation via MCP form elicitation.
15
+ *
16
+ * Shows a message with the operation details — the user simply accepts or
17
+ * declines. No form fields or checkboxes.
18
+ *
19
+ * If the client doesn't support elicitation (or the call throws),
20
+ * proceeds silently — the LLM already chose to call the tool.
21
+ */
22
+ export declare function confirmViaElicitation({ server, toolName, message, }: {
23
+ server: McpServer;
24
+ toolName: string;
25
+ message: string;
26
+ }): Promise<ElicitationResult>;
27
+ //# sourceMappingURL=elicitation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elicitation.d.ts","sourceRoot":"","sources":["../../src/utils/elicitation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAKxE,MAAM,WAAW,iBAAiB;IAChC,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,MAAM,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;CACnC;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CAAC,EAC1C,MAAM,EACN,QAAQ,EACR,OAAO,GACR,EAAE;IACD,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAgC7B"}
@@ -0,0 +1,50 @@
1
+ import { createLogger } from "./logger.js";
2
+ const log = createLogger("elicitation");
3
+ /**
4
+ * Check whether the connected client advertises form elicitation support.
5
+ */
6
+ export function clientSupportsElicitation(server) {
7
+ const caps = server.getClientCapabilities();
8
+ return !!caps?.elicitation?.form;
9
+ }
10
+ /**
11
+ * Prompt the user to confirm a write operation via MCP form elicitation.
12
+ *
13
+ * Shows a message with the operation details — the user simply accepts or
14
+ * declines. No form fields or checkboxes.
15
+ *
16
+ * If the client doesn't support elicitation (or the call throws),
17
+ * proceeds silently — the LLM already chose to call the tool.
18
+ */
19
+ export async function confirmViaElicitation({ server, toolName, message, }) {
20
+ if (!clientSupportsElicitation(server.server)) {
21
+ log.debug("Client does not support elicitation, proceeding", { toolName });
22
+ return { proceed: true };
23
+ }
24
+ try {
25
+ const result = await server.server.elicitInput({
26
+ mode: "form",
27
+ message,
28
+ requestedSchema: {
29
+ type: "object",
30
+ properties: {},
31
+ },
32
+ });
33
+ log.info("Elicitation response", { toolName, action: result.action });
34
+ if (result.action === "accept") {
35
+ return { proceed: true };
36
+ }
37
+ if (result.action === "decline") {
38
+ return { proceed: false, reason: "declined" };
39
+ }
40
+ return { proceed: false, reason: "cancelled" };
41
+ }
42
+ catch (err) {
43
+ log.warn("Elicitation failed, proceeding without confirmation", {
44
+ toolName,
45
+ error: String(err),
46
+ });
47
+ return { proceed: true };
48
+ }
49
+ }
50
+ //# sourceMappingURL=elicitation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elicitation.js","sourceRoot":"","sources":["../../src/utils/elicitation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,GAAG,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;AASxC;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAc;IACtD,MAAM,IAAI,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAC;IAC5C,OAAO,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC;AACnC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,EAC1C,MAAM,EACN,QAAQ,EACR,OAAO,GAKR;IACC,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9C,GAAG,CAAC,KAAK,CAAC,iDAAiD,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC3E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;YAC7C,IAAI,EAAE,MAAM;YACZ,OAAO;YACP,eAAe,EAAE;gBACf,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE;aACf;SACF,CAAC,CAAC;QAEH,GAAG,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAEtE,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;QAChD,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,qDAAqD,EAAE;YAC9D,QAAQ;YACR,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC;SACnB,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC"}
@@ -3,7 +3,7 @@ import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
3
3
  * Error handling convention for tool handlers:
4
4
  *
5
5
  * return errorResult(msg) — for user-fixable problems the LLM can act on:
6
- * bad resource_type, missing confirmation, unsupported operation, missing
6
+ * bad resource_type, unsupported operation, missing
7
7
  * required fields, validation errors. These are plain Errors thrown by the
8
8
  * registry/toolset layer. The LLM sees the message and can retry/adjust.
9
9
  *
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "harness-mcp-v2",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "MCP server for Harness.io CI/CD platform — 10 consolidated tools with registry-based dispatch",
5
5
  "type": "module",
6
6
  "main": "build/index.js",
7
7
  "bin": {
8
- "harness-poc-mcp-server": "build/index.js"
8
+ "harness-mcp-v2": "build/index.js"
9
9
  },
10
10
  "files": [
11
11
  "build/"
@@ -35,12 +35,12 @@
35
35
  "license": "Apache-2.0",
36
36
  "repository": {
37
37
  "type": "git",
38
- "url": "https://github.com/thisrohangupta/harness-poc-mcp.git"
38
+ "url": "https://github.com/thisrohangupta/harness-mcp-v2.git"
39
39
  },
40
40
  "bugs": {
41
- "url": "https://github.com/thisrohangupta/harness-poc-mcp/issues"
41
+ "url": "https://github.com/thisrohangupta/harness-mcp-v2/issues"
42
42
  },
43
- "homepage": "https://github.com/thisrohangupta/harness-poc-mcp#readme",
43
+ "homepage": "https://github.com/thisrohangupta/harness-mcp-v2#readme",
44
44
  "dependencies": {
45
45
  "@modelcontextprotocol/sdk": "^1.12.1",
46
46
  "express": "^5.2.1",