harness-mcp-v2 0.9.6 → 2.9.7

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 (196) hide show
  1. package/README.md +145 -90
  2. package/build/audit/index.d.ts +14 -0
  3. package/build/audit/index.d.ts.map +1 -0
  4. package/build/audit/index.js +50 -0
  5. package/build/audit/index.js.map +1 -0
  6. package/build/audit/manager.d.ts +14 -0
  7. package/build/audit/manager.d.ts.map +1 -0
  8. package/build/audit/manager.js +55 -0
  9. package/build/audit/manager.js.map +1 -0
  10. package/build/audit/sinks/jsonl-file.d.ts +13 -0
  11. package/build/audit/sinks/jsonl-file.d.ts.map +1 -0
  12. package/build/audit/sinks/jsonl-file.js +37 -0
  13. package/build/audit/sinks/jsonl-file.js.map +1 -0
  14. package/build/audit/sinks/otel.d.ts +36 -0
  15. package/build/audit/sinks/otel.d.ts.map +1 -0
  16. package/build/audit/sinks/otel.js +213 -0
  17. package/build/audit/sinks/otel.js.map +1 -0
  18. package/build/audit/sinks/stderr.d.ts +10 -0
  19. package/build/audit/sinks/stderr.d.ts.map +1 -0
  20. package/build/audit/sinks/stderr.js +22 -0
  21. package/build/audit/sinks/stderr.js.map +1 -0
  22. package/build/audit/sinks/webhook.d.ts +29 -0
  23. package/build/audit/sinks/webhook.d.ts.map +1 -0
  24. package/build/audit/sinks/webhook.js +102 -0
  25. package/build/audit/sinks/webhook.js.map +1 -0
  26. package/build/audit/types.d.ts +48 -0
  27. package/build/audit/types.d.ts.map +1 -0
  28. package/build/audit/types.js +2 -0
  29. package/build/audit/types.js.map +1 -0
  30. package/build/client/harness-client.d.ts +1 -0
  31. package/build/client/harness-client.d.ts.map +1 -1
  32. package/build/client/harness-client.js +28 -15
  33. package/build/client/harness-client.js.map +1 -1
  34. package/build/client/types.d.ts +3 -0
  35. package/build/client/types.d.ts.map +1 -1
  36. package/build/config.d.ts +29 -2
  37. package/build/config.d.ts.map +1 -1
  38. package/build/config.js +26 -6
  39. package/build/config.js.map +1 -1
  40. package/build/data/schemas/v0/pipeline.d.ts.map +1 -1
  41. package/build/data/schemas/v0/pipeline.js +223 -0
  42. package/build/data/schemas/v0/pipeline.js.map +1 -1
  43. package/build/data/schemas/v0/template.d.ts.map +1 -1
  44. package/build/data/schemas/v0/template.js +307 -0
  45. package/build/data/schemas/v0/template.js.map +1 -1
  46. package/build/index.js +28 -17
  47. package/build/index.js.map +1 -1
  48. package/build/registry/extractors.d.ts +9 -0
  49. package/build/registry/extractors.d.ts.map +1 -1
  50. package/build/registry/extractors.js +19 -0
  51. package/build/registry/extractors.js.map +1 -1
  52. package/build/registry/index.d.ts +14 -2
  53. package/build/registry/index.d.ts.map +1 -1
  54. package/build/registry/index.js +105 -16
  55. package/build/registry/index.js.map +1 -1
  56. package/build/registry/toolsets/access-control.d.ts.map +1 -1
  57. package/build/registry/toolsets/access-control.js +23 -0
  58. package/build/registry/toolsets/access-control.js.map +1 -1
  59. package/build/registry/toolsets/agents.d.ts.map +1 -1
  60. package/build/registry/toolsets/agents.js +5 -0
  61. package/build/registry/toolsets/agents.js.map +1 -1
  62. package/build/registry/toolsets/ai-evals.d.ts.map +1 -1
  63. package/build/registry/toolsets/ai-evals.js +90 -0
  64. package/build/registry/toolsets/ai-evals.js.map +1 -1
  65. package/build/registry/toolsets/audit.d.ts.map +1 -1
  66. package/build/registry/toolsets/audit.js +2 -0
  67. package/build/registry/toolsets/audit.js.map +1 -1
  68. package/build/registry/toolsets/ccm.d.ts.map +1 -1
  69. package/build/registry/toolsets/ccm.js +437 -57
  70. package/build/registry/toolsets/ccm.js.map +1 -1
  71. package/build/registry/toolsets/chaos.d.ts.map +1 -1
  72. package/build/registry/toolsets/chaos.js +86 -0
  73. package/build/registry/toolsets/chaos.js.map +1 -1
  74. package/build/registry/toolsets/connectors.d.ts.map +1 -1
  75. package/build/registry/toolsets/connectors.js +7 -0
  76. package/build/registry/toolsets/connectors.js.map +1 -1
  77. package/build/registry/toolsets/dashboards.d.ts.map +1 -1
  78. package/build/registry/toolsets/dashboards.js +2 -0
  79. package/build/registry/toolsets/dashboards.js.map +1 -1
  80. package/build/registry/toolsets/dbops.d.ts.map +1 -1
  81. package/build/registry/toolsets/dbops.js +142 -21
  82. package/build/registry/toolsets/dbops.js.map +1 -1
  83. package/build/registry/toolsets/delegates.d.ts.map +1 -1
  84. package/build/registry/toolsets/delegates.js +7 -0
  85. package/build/registry/toolsets/delegates.js.map +1 -1
  86. package/build/registry/toolsets/environments.d.ts.map +1 -1
  87. package/build/registry/toolsets/environments.js +6 -0
  88. package/build/registry/toolsets/environments.js.map +1 -1
  89. package/build/registry/toolsets/feature-flags.d.ts.map +1 -1
  90. package/build/registry/toolsets/feature-flags.js +74 -1
  91. package/build/registry/toolsets/feature-flags.js.map +1 -1
  92. package/build/registry/toolsets/freeze.d.ts.map +1 -1
  93. package/build/registry/toolsets/freeze.js +8 -0
  94. package/build/registry/toolsets/freeze.js.map +1 -1
  95. package/build/registry/toolsets/gitops.d.ts.map +1 -1
  96. package/build/registry/toolsets/gitops.js +30 -0
  97. package/build/registry/toolsets/gitops.js.map +1 -1
  98. package/build/registry/toolsets/governance.d.ts.map +1 -1
  99. package/build/registry/toolsets/governance.js +12 -0
  100. package/build/registry/toolsets/governance.js.map +1 -1
  101. package/build/registry/toolsets/idp.d.ts.map +1 -1
  102. package/build/registry/toolsets/idp.js +13 -0
  103. package/build/registry/toolsets/idp.js.map +1 -1
  104. package/build/registry/toolsets/infrastructure.d.ts.map +1 -1
  105. package/build/registry/toolsets/infrastructure.js +6 -0
  106. package/build/registry/toolsets/infrastructure.js.map +1 -1
  107. package/build/registry/toolsets/logs.d.ts.map +1 -1
  108. package/build/registry/toolsets/logs.js +1 -0
  109. package/build/registry/toolsets/logs.js.map +1 -1
  110. package/build/registry/toolsets/overrides.d.ts.map +1 -1
  111. package/build/registry/toolsets/overrides.js +5 -0
  112. package/build/registry/toolsets/overrides.js.map +1 -1
  113. package/build/registry/toolsets/pipelines.d.ts.map +1 -1
  114. package/build/registry/toolsets/pipelines.js +32 -0
  115. package/build/registry/toolsets/pipelines.js.map +1 -1
  116. package/build/registry/toolsets/platform.d.ts.map +1 -1
  117. package/build/registry/toolsets/platform.js +12 -2
  118. package/build/registry/toolsets/platform.js.map +1 -1
  119. package/build/registry/toolsets/pull-requests.d.ts.map +1 -1
  120. package/build/registry/toolsets/pull-requests.js +13 -0
  121. package/build/registry/toolsets/pull-requests.js.map +1 -1
  122. package/build/registry/toolsets/registries.d.ts.map +1 -1
  123. package/build/registry/toolsets/registries.js +5 -0
  124. package/build/registry/toolsets/registries.js.map +1 -1
  125. package/build/registry/toolsets/repositories.d.ts.map +1 -1
  126. package/build/registry/toolsets/repositories.js +27 -4
  127. package/build/registry/toolsets/repositories.js.map +1 -1
  128. package/build/registry/toolsets/scs.d.ts.map +1 -1
  129. package/build/registry/toolsets/scs.js +25 -0
  130. package/build/registry/toolsets/scs.js.map +1 -1
  131. package/build/registry/toolsets/secrets.d.ts.map +1 -1
  132. package/build/registry/toolsets/secrets.js +2 -0
  133. package/build/registry/toolsets/secrets.js.map +1 -1
  134. package/build/registry/toolsets/sei.d.ts.map +1 -1
  135. package/build/registry/toolsets/sei.js +18 -0
  136. package/build/registry/toolsets/sei.js.map +1 -1
  137. package/build/registry/toolsets/services.d.ts.map +1 -1
  138. package/build/registry/toolsets/services.js +5 -0
  139. package/build/registry/toolsets/services.js.map +1 -1
  140. package/build/registry/toolsets/settings.d.ts.map +1 -1
  141. package/build/registry/toolsets/settings.js +1 -0
  142. package/build/registry/toolsets/settings.js.map +1 -1
  143. package/build/registry/toolsets/sto.d.ts.map +1 -1
  144. package/build/registry/toolsets/sto.js +6 -0
  145. package/build/registry/toolsets/sto.js.map +1 -1
  146. package/build/registry/toolsets/templates.d.ts.map +1 -1
  147. package/build/registry/toolsets/templates.js +5 -0
  148. package/build/registry/toolsets/templates.js.map +1 -1
  149. package/build/registry/types.d.ts +43 -12
  150. package/build/registry/types.d.ts.map +1 -1
  151. package/build/registry/types.js +39 -1
  152. package/build/registry/types.js.map +1 -1
  153. package/build/resources/execution-summary.js +1 -1
  154. package/build/resources/execution-summary.js.map +1 -1
  155. package/build/resources/pipeline-yaml.js +2 -2
  156. package/build/resources/pipeline-yaml.js.map +1 -1
  157. package/build/tools/harness-create.d.ts.map +1 -1
  158. package/build/tools/harness-create.js +3 -6
  159. package/build/tools/harness-create.js.map +1 -1
  160. package/build/tools/harness-delete.d.ts.map +1 -1
  161. package/build/tools/harness-delete.js +2 -5
  162. package/build/tools/harness-delete.js.map +1 -1
  163. package/build/tools/harness-diagnose.js +1 -1
  164. package/build/tools/harness-diagnose.js.map +1 -1
  165. package/build/tools/harness-execute.d.ts.map +1 -1
  166. package/build/tools/harness-execute.js +7 -8
  167. package/build/tools/harness-execute.js.map +1 -1
  168. package/build/tools/harness-search.js +1 -1
  169. package/build/tools/harness-search.js.map +1 -1
  170. package/build/tools/harness-status.js +3 -3
  171. package/build/tools/harness-status.js.map +1 -1
  172. package/build/tools/harness-update.d.ts.map +1 -1
  173. package/build/tools/harness-update.js +3 -6
  174. package/build/tools/harness-update.js.map +1 -1
  175. package/build/utils/cli.d.ts +1 -0
  176. package/build/utils/cli.d.ts.map +1 -1
  177. package/build/utils/cli.js +1 -1
  178. package/build/utils/cli.js.map +1 -1
  179. package/build/utils/elicitation.d.ts +14 -13
  180. package/build/utils/elicitation.d.ts.map +1 -1
  181. package/build/utils/elicitation.js +32 -31
  182. package/build/utils/elicitation.js.map +1 -1
  183. package/build/utils/log-resolver.js +1 -1
  184. package/build/utils/log-resolver.js.map +1 -1
  185. package/build/utils/logger.d.ts +9 -0
  186. package/build/utils/logger.d.ts.map +1 -1
  187. package/build/utils/logger.js +5 -0
  188. package/build/utils/logger.js.map +1 -1
  189. package/build/utils/redact.d.ts +11 -0
  190. package/build/utils/redact.d.ts.map +1 -0
  191. package/build/utils/redact.js +59 -0
  192. package/build/utils/redact.js.map +1 -0
  193. package/build/utils/zip-csv.d.ts.map +1 -1
  194. package/build/utils/zip-csv.js +2 -1
  195. package/build/utils/zip-csv.js.map +1 -1
  196. package/package.json +29 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ## Harness MCP Server 2.0
2
2
 
3
- An MCP (Model Context Protocol) server that gives AI agents full access to the Harness.io platform through 11 consolidated tools and 163 resource types.
3
+ An MCP (Model Context Protocol) server that gives AI agents full access to the Harness.io platform through 11 consolidated tools and 167 resource types.
4
4
 
5
5
  ## Why Use This MCP Server
6
6
 
@@ -8,10 +8,10 @@ Most MCP servers map one tool per API endpoint. For a platform as broad as Harne
8
8
 
9
9
  This server is built differently:
10
10
 
11
- - **11 tools, 163 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 11 tools instead of hundreds.
12
- - **Full platform coverage.** 31 toolsets spanning CI/CD, GitOps, Feature Flags, Cloud Cost Management, Security Testing, Chaos Engineering, Internal Developer Portal, Software Supply Chain, Governance, Service Overrides, Visualizations, and more. Not just pipelines — the entire Harness platform.
11
+ - **11 tools, 167 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 11 tools instead of hundreds.
12
+ - **Full platform coverage.** 31 toolsets spanning CI/CD, GitOps, Feature Flags, Cloud Cost Management, Security Testing, Chaos Engineering, Database DevOps, Internal Developer Portal, Software Supply Chain, Governance, Service Overrides, Visualizations, and more. Not just pipelines — the entire Harness platform.
13
13
  - **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.
14
- - **27 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.
14
+ - **30 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.
15
15
  - **Works everywhere.** Stdio transport for local clients (Claude Desktop, Cursor, Windsurf), HTTP transport for remote/shared deployments, Docker and Kubernetes ready.
16
16
  - **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.
17
17
  - **Extensible by design.** Adding a new Harness resource means adding a declarative data file — no new tool registration, no schema changes, no prompt updates.
@@ -72,7 +72,7 @@ For development or customization:
72
72
 
73
73
  ```bash
74
74
  git clone https://github.com/harness/mcp-server.git
75
- cd harness-mcp-v2
75
+ cd mcp-server
76
76
  pnpm install
77
77
  pnpm build
78
78
 
@@ -84,7 +84,7 @@ pnpm inspect # Test with MCP Inspector
84
84
 
85
85
  ### Anthropic MCP Directory bundle
86
86
 
87
- The MCPB bundle manifest lives in [`mcp-directory/`](mcp-directory/), and the bundle icon is tracked at [`icon.png`](icon.png) in the repository root. Copy `mcp-directory/manifest.json` to the bundle root after `pnpm build` so the generated archive contains root-level `manifest.json`, `icon.png`, `build/`, `package.json`, and production `node_modules/`.
87
+ The MCPB bundle manifest lives in `[mcp-directory/](mcp-directory/)`, and the bundle icon is tracked at `[icon.png](icon.png)` in the repository root. Copy `mcp-directory/manifest.json` to the bundle root after `pnpm build` so the generated archive contains root-level `manifest.json`, `icon.png`, `build/`, `package.json`, and production `node_modules/`.
88
88
 
89
89
  To keep the archive small, build MCPB packages from a staging directory:
90
90
 
@@ -162,6 +162,8 @@ curl -X DELETE http://localhost:3000/mcp \
162
162
  Harness also supports a hosted MCP endpoint for accounts that have the managed service enabled. This is useful when you want a shared remote MCP endpoint instead of running `npx harness-mcp-v2` or self-hosting the HTTP transport yourself.
163
163
 
164
164
  > **Important:** Hosted MCP authentication uses **Harness Platform OAuth**. It does **not** use `HARNESS_API_KEY` in the client config. Hosted MCP availability is configured per Harness account, so you will need to work with **Harness Support** to enable/configure the setting before using it.
165
+ >
166
+ > The hosted endpoint `https://mcp.harness.io/mcp` is a managed service. Client-side MCP config in Claude, Cursor, or Cowork cannot override which Harness environment it routes to. For Harness0 or another private Harness SaaS environment, ask Harness Support to enable/configure hosted MCP for that environment, or run the local/self-hosted server and set `HARNESS_BASE_URL` to the target Harness host.
165
167
 
166
168
  **Hosted MCP example:**
167
169
 
@@ -243,8 +245,6 @@ npx (zero install)
243
245
  }
244
246
  ```
245
247
 
246
-
247
-
248
248
  node (local install)
249
249
 
250
250
  ```bash
@@ -264,8 +264,6 @@ npm install -g harness-mcp-v2
264
264
  }
265
265
  ```
266
266
 
267
-
268
-
269
267
  #### Claude Code (via `claude mcp add`)
270
268
 
271
269
  npx (zero install)
@@ -274,8 +272,6 @@ npx (zero install)
274
272
  claude mcp add harness -- npx harness-mcp-v2
275
273
  ```
276
274
 
277
-
278
-
279
275
  node (local install)
280
276
 
281
277
  ```bash
@@ -283,8 +279,6 @@ npm install -g harness-mcp-v2
283
279
  claude mcp add harness -- harness-mcp-v2
284
280
  ```
285
281
 
286
-
287
-
288
282
  Then set `HARNESS_API_KEY` in your environment or `.env` file.
289
283
 
290
284
  #### Cursor (`.cursor/mcp.json`)
@@ -305,8 +299,6 @@ npx (zero install)
305
299
  }
306
300
  ```
307
301
 
308
-
309
-
310
302
  node (local install)
311
303
 
312
304
  ```bash
@@ -326,8 +318,6 @@ npm install -g harness-mcp-v2
326
318
  }
327
319
  ```
328
320
 
329
-
330
-
331
321
  #### Windsurf (`~/.windsurf/mcp.json`)
332
322
 
333
323
  npx (zero install)
@@ -346,8 +336,6 @@ npx (zero install)
346
336
  }
347
337
  ```
348
338
 
349
-
350
-
351
339
  node (local install)
352
340
 
353
341
  ```bash
@@ -367,8 +355,6 @@ npm install -g harness-mcp-v2
367
355
  }
368
356
  ```
369
357
 
370
-
371
-
372
358
  Using a local build from source?
373
359
 
374
360
  Replace the command with the path to your built `index.js`:
@@ -380,8 +366,6 @@ Replace the command with the path to your built `index.js`:
380
366
  }
381
367
  ```
382
368
 
383
-
384
-
385
369
  ### MCP Gateway
386
370
 
387
371
  The Harness MCP server is fully compatible with MCP Gateways — reverse proxies that provide centralized authentication, governance, tool routing, and observability across multiple MCP servers. Since the server implements the standard MCP protocol with both stdio and HTTP transports, it works behind any MCP-compliant gateway with no code changes.
@@ -507,25 +491,28 @@ The deployment runs 2 replicas with readiness/liveness probes, resource limits,
507
491
 
508
492
  The server automatically loads environment variables from a `.env` file in the project root if one exists. Copy `.env.example` to `.env` and fill in your values. Environment variables can also be set via your shell or MCP client config.
509
493
 
510
- | Variable | Required | Default | Description |
511
- |----------|----------|---------|-------------|
512
- | `HARNESS_API_KEY` | Yes | -- | Harness personal access token or service account token |
513
- | `HARNESS_ACCOUNT_ID` | No | *(from PAT)* | Harness account identifier. Auto-extracted from PAT tokens; only needed for non-PAT API keys |
514
- | `HARNESS_BASE_URL` | No | `https://app.harness.io` | Base URL (override for self-managed Harness) |
515
- | `HARNESS_ORG` | No | `default` | Organization ID. Used when `org_id` is not specified per tool call. Agents can also discover orgs dynamically via `harness_list(resource_type="organization")` |
516
- | `HARNESS_PROJECT` | No | -- | Project ID. Used when `project_id` is not specified per tool call. Agents can also discover projects dynamically via `harness_list(resource_type="project")` |
517
- | `HARNESS_API_TIMEOUT_MS` | No | `30000` | HTTP request timeout in milliseconds |
518
- | `HARNESS_MAX_RETRIES` | No | `3` | Retry count for transient failures (429, 5xx) |
519
- | `HARNESS_MAX_BODY_SIZE_MB` | No | `10` | Max HTTP request body size in MB for `http` transport |
520
- | `HARNESS_RATE_LIMIT_RPS` | No | `10` | Client-side request throttle (requests per second) to Harness APIs |
521
- | `LOG_LEVEL` | No | `info` | Log verbosity: `debug`, `info`, `warn`, `error` |
522
- | `HARNESS_TOOLSETS` | No | *(defaults)* | Comma-separated toolset list. Empty loads default toolsets and excludes opt-in toolsets such as `ai-evals`. Supports `+name` to add opt-in toolsets and `-name` to remove defaults (see [Toolset Filtering](#toolset-filtering)) |
523
- | `HARNESS_READ_ONLY` | No | `false` | Block all mutating operations (create, update, delete, execute). Only list and get are allowed. Useful for shared/demo environments |
524
- | `HARNESS_SKIP_ELICITATION` | No | `false` | Skip all elicitation confirmation prompts. When `true`, write and delete operations proceed without user approval enabling fully autonomous agent workflows. See [Elicitation](#elicitation) |
525
- | `HARNESS_ALLOW_HTTP` | No | `false` | Allow non-HTTPS `HARNESS_BASE_URL`. By default, the server enforces HTTPS for security. Set to `true` only for local development against a non-TLS Harness instance |
526
- | `HARNESS_PIPELINE_VERSION` | No | `0` | **(Alpha)** Pipeline YAML version. `0` loads the `pipeline` resource type and excludes `pipeline_v1`; `1` loads `pipeline_v1` and excludes `pipeline`. HTTP sessions can override this at initialize time with `x-harness-pipeline-version: 0` or `1` |
527
- | `HARNESS_MCP_ALLOWED_HOSTS` | No | -- | Comma-separated hostnames allowed by HTTP transport Host-header validation. `mcp.harness.io` is allowed by default for localhost binds; add proxy/custom domains here |
528
- | `HARNESS_MCP_LOG_FILE` | No | `~/.claude/harness-mcp.log` | File used for stdio disconnect/crash diagnostics when stderr may no longer be available |
494
+
495
+ | Variable | Required | Default | Description |
496
+ | --------------------------- | -------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
497
+ | `HARNESS_API_KEY` | Yes | -- | Harness personal access token or service account token |
498
+ | `HARNESS_ACCOUNT_ID` | No | *(from PAT)* | Harness account identifier. Auto-extracted from PAT tokens; only needed for non-PAT API keys |
499
+ | `HARNESS_BASE_URL` | No | `https://app.harness.io` | Harness API/UI base URL for local stdio or self-hosted HTTP deployments. Set this to environments such as `https://harness0.harness.io` when running the server yourself. It does not affect the managed `https://mcp.harness.io/mcp` hosted endpoint |
500
+ | `HARNESS_ORG` | No | `default` | Organization ID. Used when `org_id` is not specified per tool call. Agents can also discover orgs dynamically via `harness_list(resource_type="organization")` |
501
+ | `HARNESS_PROJECT` | No | -- | Project ID. Used when `project_id` is not specified per tool call. Agents can also discover projects dynamically via `harness_list(resource_type="project")` |
502
+ | `HARNESS_API_TIMEOUT_MS` | No | `30000` | HTTP request timeout in milliseconds |
503
+ | `HARNESS_MAX_RETRIES` | No | `3` | Retry count for transient failures (429, 5xx) |
504
+ | `HARNESS_MAX_BODY_SIZE_MB` | No | `10` | Max HTTP request body size in MB for `http` transport |
505
+ | `HARNESS_RATE_LIMIT_RPS` | No | `10` | Client-side request throttle (requests per second) to Harness APIs |
506
+ | `LOG_LEVEL` | No | `info` | Log verbosity: `debug`, `info`, `warn`, `error` |
507
+ | `HARNESS_TOOLSETS` | No | *(defaults)* | Comma-separated toolset list. Empty loads default toolsets and excludes opt-in toolsets such as `ai-evals`. Supports `+name` to add opt-in toolsets and `-name` to remove defaults (see [Toolset Filtering](#toolset-filtering)) |
508
+ | `HARNESS_READ_ONLY` | No | `false` | Block all mutating operations (create, update, delete, execute). Only list and get are allowed. Useful for shared/demo environments |
509
+ | `HARNESS_AUTO_APPROVE_RISK` | No | `none` | Risk-based auto-approve threshold for autonomous workflows. Operations at or below this risk proceed without confirmation. Values: `none`, `low_write`, `medium_write`, `high_write`, `all`. See [Elicitation](#elicitation) |
510
+ | `HARNESS_SKIP_ELICITATION` | No | `false` | **Deprecated** use `HARNESS_AUTO_APPROVE_RISK=all` instead. Kept for backward compatibility |
511
+ | `HARNESS_ALLOW_HTTP` | No | `false` | Allow non-HTTPS `HARNESS_BASE_URL`. By default, the server enforces HTTPS for security. Set to `true` only for local development against a non-TLS Harness instance |
512
+ | `HARNESS_PIPELINE_VERSION` | No | `0` | **(Alpha)** Pipeline YAML version. `0` loads the `pipeline` resource type and excludes `pipeline_v1`; `1` loads `pipeline_v1` and excludes `pipeline`. HTTP sessions can override this at initialize time with `x-harness-pipeline-version: 0` or `1` |
513
+ | `HARNESS_MCP_ALLOWED_HOSTS` | No | -- | Comma-separated hostnames allowed by HTTP transport Host-header validation. `mcp.harness.io` is allowed by default for localhost binds; add proxy/custom domains here |
514
+ | `HARNESS_MCP_LOG_FILE` | No | `~/.claude/harness-mcp.log` | File used for stdio disconnect/crash diagnostics when stderr may no longer be available |
515
+
529
516
 
530
517
  ### HTTPS Enforcement
531
518
 
@@ -680,6 +667,49 @@ The server exposes 11 MCP tools. Most API tools accept `org_id` and `project_id`
680
667
  { "org_id": "default", "project_id": "my-project", "limit": 5 }
681
668
  ```
682
669
 
670
+ **List database schemas filtered by migration type:**
671
+
672
+ ```json
673
+ { "resource_type": "database_schema", "migration_type": "Liquibase" }
674
+ ```
675
+
676
+ **List database instances for a schema:**
677
+
678
+ ```json
679
+ { "resource_type": "database_instance", "dbschema_id": "my_schema" }
680
+ ```
681
+
682
+ **Get the resolved LLM authoring pipeline for a schema and instance:**
683
+
684
+ ```json
685
+ { "resource_type": "database_llm_authoring_pipeline", "resource_id": "my_schema", "dbinstance_id": "prod_db" }
686
+ ```
687
+
688
+ **List snapshot object names (e.g. tables) for a schema instance:**
689
+
690
+ ```json
691
+ {
692
+ "resource_type": "database_snapshot_object",
693
+ "dbschema_id": "my_schema",
694
+ "dbinstance_id": "prod_db",
695
+ "object_type": "Table"
696
+ }
697
+ ```
698
+
699
+ **Get full snapshot metadata for specific named objects:**
700
+
701
+ ```json
702
+ {
703
+ "resource_type": "database_snapshot_object",
704
+ "resource_id": "prod_db",
705
+ "params": {
706
+ "dbschema_id": "my_schema",
707
+ "object_type": "Table",
708
+ "object_names": ["users", "orders"]
709
+ }
710
+ }
711
+ ```
712
+
683
713
  ### Pipeline Run Workflow (Recommended)
684
714
 
685
715
  Use this sequence to reduce execution-time input errors:
@@ -924,7 +954,7 @@ Harness pipelines can be stored in three ways:
924
954
 
925
955
  ## Resource Types
926
956
 
927
- 163 resource types organized across 31 toolsets. Each resource type supports a subset of CRUD operations and optional execute actions.
957
+ 167 resource types organized across 31 toolsets. Each resource type supports a subset of CRUD operations and optional execute actions.
928
958
 
929
959
  ### Platform
930
960
 
@@ -1069,6 +1099,17 @@ Only one pipeline YAML resource type is loaded at startup. By default `HARNESS_P
1069
1099
  | `dashboard_data` | | x | | | | |
1070
1100
 
1071
1101
 
1102
+ ### Database DevOps
1103
+
1104
+
1105
+ | Resource Type | List | Get | Create | Update | Delete | Execute Actions |
1106
+ | --------------------------------- | ---- | --- | ------ | ------ | ------ | --------------- |
1107
+ | `database_schema` | x | x | | | | |
1108
+ | `database_instance` | x | x | | | | |
1109
+ | `database_snapshot_object` | x | x | | | | |
1110
+ | `database_llm_authoring_pipeline` | | x | | | | |
1111
+
1112
+
1072
1113
  ### Internal Developer Portal (IDP)
1073
1114
 
1074
1115
 
@@ -1359,7 +1400,7 @@ Inline PNG chart visualizations rendered from Harness data. These are metadata-o
1359
1400
 
1360
1401
  ## Toolset Filtering
1361
1402
 
1362
- By default, 30 of 31 toolsets are enabled. One toolset (`ai-evals`) is opt-in — excluded by default to avoid polluting the resource list for users who don't need it.
1403
+ By default, 31 of 32 toolsets are enabled. One toolset (`ai-evals`) is opt-in — excluded by default to avoid polluting the resource list for users who don't need it.
1363
1404
 
1364
1405
  ### Enabling opt-in toolsets
1365
1406
 
@@ -1397,40 +1438,43 @@ HARNESS_TOOLSETS=pipelines,services,connectors
1397
1438
 
1398
1439
  Available toolset names:
1399
1440
 
1400
- | Toolset | Resource Types |
1401
- |---------|---------------|
1402
- | `platform` | organization, project |
1403
- | `pipelines` | pipeline, pipeline_v1, execution, trigger, pipeline_summary, input_set, approval_instance |
1404
- | `agents` | agent, agent_run |
1405
- | `services` | service |
1406
- | `environments` | environment |
1407
- | `connectors` | connector, connector_catalogue |
1408
- | `infrastructure` | infrastructure |
1409
- | `secrets` | secret |
1410
- | `logs` | execution_log |
1411
- | `audit` | audit_event |
1412
- | `delegates` | delegate, delegate_token |
1413
- | `repositories` | repository, branch, commit, file_content, tag, repo_rule, space_rule |
1414
- | `registries` | registry, artifact, artifact_version, artifact_file |
1415
- | `templates` | template |
1416
- | `dashboards` | dashboard, dashboard_data |
1417
- | `idp` | idp_entity, scorecard, scorecard_check, scorecard_stats, scorecard_check_stats, idp_score, idp_workflow, idp_tech_doc |
1418
- | `pull-requests` | pull_request, pr_reviewer, pr_comment, pr_check, pr_activity |
1419
- | `feature-flags` | fme_workspace, fme_environment, fme_feature_flag, fme_feature_flag_definition, fme_rollout_status, fme_rule_based_segment, fme_rule_based_segment_definition, feature_flag |
1420
- | `gitops` | gitops_agent, gitops_application, gitops_cluster, gitops_repository, gitops_applicationset, gitops_repo_credential, gitops_app_event, gitops_pod_log, gitops_managed_resource, gitops_resource_action, gitops_dashboard, gitops_app_resource_tree |
1421
- | `chaos` | chaos_experiment, chaos_probe, chaos_experiment_template, chaos_infrastructure, chaos_experiment_variable, chaos_experiment_run, chaos_loadtest, chaos_k8s_infrastructure, chaos_hub, chaos_fault, chaos_network_map, chaos_guard_condition, chaos_guard_rule, chaos_recommendation, chaos_risk |
1422
- | `ccm` | cost_perspective, cost_breakdown, cost_timeseries, cost_summary, cost_recommendation, cost_anomaly, cost_anomaly_summary, cost_category, cost_account_overview, cost_filter_value, cost_recommendation_stats, cost_recommendation_detail, cost_commitment |
1423
- | `sei` | sei_metric, sei_productivity_metric, sei_dora_metric, sei_team, sei_team_detail, sei_org_tree, sei_org_tree_detail, sei_business_alignment, sei_ai_usage, sei_ai_adoption, sei_ai_impact, sei_ai_raw_metric |
1424
- | `scs` | scs_artifact_source, artifact_security, scs_artifact_component, scs_artifact_remediation, scs_chain_of_custody, scs_compliance_result, code_repo_security, scs_sbom |
1425
- | `sto` | security_issue, security_issue_filter, security_exemption |
1426
- | `access_control` | user, user_group, service_account, role, role_assignment, resource_group, permission |
1427
- | `governance` | policy, policy_set, policy_evaluation |
1428
- | `freeze` | freeze_window, global_freeze |
1429
- | `overrides` | service_override |
1430
- | `settings` | setting |
1431
- | `visualizations` | visual_timeline, visual_stage_flow, visual_health_dashboard, visual_pie_chart, visual_bar_chart, visual_timeseries, visual_architecture |
1441
+
1442
+ | Toolset | Resource Types |
1443
+ | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1444
+ | `platform` | organization, project |
1445
+ | `pipelines` | pipeline, pipeline_v1, execution, trigger, pipeline_summary, input_set, approval_instance |
1446
+ | `agents` | agent, agent_run |
1447
+ | `services` | service |
1448
+ | `environments` | environment |
1449
+ | `connectors` | connector, connector_catalogue |
1450
+ | `infrastructure` | infrastructure |
1451
+ | `secrets` | secret |
1452
+ | `logs` | execution_log |
1453
+ | `audit` | audit_event |
1454
+ | `delegates` | delegate, delegate_token |
1455
+ | `repositories` | repository, branch, commit, file_content, tag, repo_rule, space_rule |
1456
+ | `registries` | registry, artifact, artifact_version, artifact_file |
1457
+ | `templates` | template |
1458
+ | `dashboards` | dashboard, dashboard_data |
1459
+ | `idp` | idp_entity, scorecard, scorecard_check, scorecard_stats, scorecard_check_stats, idp_score, idp_workflow, idp_tech_doc |
1460
+ | `pull-requests` | pull_request, pr_reviewer, pr_comment, pr_check, pr_activity |
1461
+ | `feature-flags` | fme_workspace, fme_environment, fme_feature_flag, fme_feature_flag_definition, fme_rollout_status, fme_rule_based_segment, fme_rule_based_segment_definition, feature_flag |
1462
+ | `gitops` | gitops_agent, gitops_application, gitops_cluster, gitops_repository, gitops_applicationset, gitops_repo_credential, gitops_app_event, gitops_pod_log, gitops_managed_resource, gitops_resource_action, gitops_dashboard, gitops_app_resource_tree |
1463
+ | `chaos` | chaos_experiment, chaos_probe, chaos_experiment_template, chaos_infrastructure, chaos_experiment_variable, chaos_experiment_run, chaos_loadtest, chaos_k8s_infrastructure, chaos_hub, chaos_fault, chaos_network_map, chaos_guard_condition, chaos_guard_rule, chaos_recommendation, chaos_risk |
1464
+ | `ccm` | cost_perspective, cost_breakdown, cost_timeseries, cost_summary, cost_recommendation, cost_anomaly, cost_anomaly_summary, cost_category, cost_account_overview, cost_filter_value, cost_recommendation_stats, cost_recommendation_detail, cost_commitment |
1465
+ | `sei` | sei_metric, sei_productivity_metric, sei_dora_metric, sei_team, sei_team_detail, sei_org_tree, sei_org_tree_detail, sei_business_alignment, sei_ai_usage, sei_ai_adoption, sei_ai_impact, sei_ai_raw_metric |
1466
+ | `scs` | scs_artifact_source, artifact_security, scs_artifact_component, scs_artifact_remediation, scs_chain_of_custody, scs_compliance_result, code_repo_security, scs_sbom |
1467
+ | `sto` | security_issue, security_issue_filter, security_exemption |
1468
+ | `dbops` | database_schema, database_instance, database_snapshot_object, database_llm_authoring_pipeline |
1469
+ | `access_control` | user, user_group, service_account, role, role_assignment, resource_group, permission |
1470
+ | `governance` | policy, policy_set, policy_evaluation |
1471
+ | `freeze` | freeze_window, global_freeze |
1472
+ | `overrides` | service_override |
1473
+ | `settings` | setting |
1474
+ | `visualizations` | visual_timeline, visual_stage_flow, visual_health_dashboard, visual_pie_chart, visual_bar_chart, visual_timeseries, visual_architecture |
1432
1475
  | `ai-evals` **(opt-in)** | eval_dataset, eval_dataset_item, evaluation, eval_run, eval_run_item, eval_run_by_eval, eval_metric, eval_metric_set, eval_metric_set_entry, eval_suite, eval_suite_evaluation, eval_suite_run, eval_target, eval_model, eval_annotation, eval_analytics, eval_git_settings, eval_registry_item |
1433
1476
 
1477
+
1434
1478
  ## Architecture
1435
1479
 
1436
1480
  ```
@@ -1446,8 +1490,8 @@ Available toolset names:
1446
1490
  |
1447
1491
  +--------v---------+
1448
1492
  | Registry | <-- Declarative resource definitions
1449
- | 31 Toolsets | (data files, not code)
1450
- | 163 Resource Types|
1493
+ | 32 Toolsets | (data files, not code)
1494
+ | 167 Resource Types|
1451
1495
  +--------+---------+
1452
1496
  |
1453
1497
  +--------v---------+
@@ -1637,20 +1681,29 @@ Write tools (`harness_create`, `harness_update`, `harness_delete`, `harness_exec
1637
1681
  | MCP Inspector | Yes |
1638
1682
 
1639
1683
 
1640
- Elicitation behavior varies by operation severity when client support is missing:
1641
- For clients that don't support elicitation:
1684
+ Elicitation behavior varies by operation risk when client support is missing:
1685
+
1642
1686
 
1643
- - `harness_create`, `harness_update`, and `harness_execute` proceed without a dialog (best effort).
1644
- - Destructive operations are blocked if confirmation cannot be obtained (`harness_delete`).
1687
+ | Risk Level | Client supports elicitation | Behavior |
1688
+ | --------------------------------------------- | --------------------------- | ------------------------------------------------- |
1689
+ | `read`, `low_write` | any | Proceed silently (no confirmation needed) |
1690
+ | `medium_write`, `high_write`, `destructive` | Yes | Prompt user — proceed on accept, block on decline |
1691
+ | `medium_write`, `high_write`, `destructive` | No | **BLOCK** (return error) |
1692
+ | any (at or below `HARNESS_AUTO_APPROVE_RISK`) | any | Auto-approve without prompting |
1645
1693
 
1646
- If elicitation fails at runtime, the same rules apply: non-destructive writes continue, destructive writes are blocked.
1647
1694
 
1648
- ### Skipping Elicitation for Autonomous Workflows
1695
+ If elicitation fails at runtime, operations at `medium_write` or above are blocked.
1649
1696
 
1650
- For fully autonomous agent workflows (CI/CD bots, headless agents, batch automation), elicitation prompts can be disabled entirely:
1697
+ ### Auto-Approve for Autonomous Workflows
1698
+
1699
+ For CI/CD bots, headless agents, or batch automation, use `HARNESS_AUTO_APPROVE_RISK` to auto-approve operations up to a given risk level:
1651
1700
 
1652
1701
  ```bash
1653
- HARNESS_SKIP_ELICITATION=true
1702
+ # Auto-approve everything (equivalent to old HARNESS_SKIP_ELICITATION=true)
1703
+ HARNESS_AUTO_APPROVE_RISK=all
1704
+
1705
+ # Auto-approve only low-risk writes, still prompt for medium+
1706
+ HARNESS_AUTO_APPROVE_RISK=low_write
1654
1707
  ```
1655
1708
 
1656
1709
  Or in your MCP client config:
@@ -1663,20 +1716,22 @@ Or in your MCP client config:
1663
1716
  "args": ["harness-mcp-v2"],
1664
1717
  "env": {
1665
1718
  "HARNESS_API_KEY": "pat.xxx.xxx.xxx",
1666
- "HARNESS_SKIP_ELICITATION": "true"
1719
+ "HARNESS_AUTO_APPROVE_RISK": "all"
1667
1720
  }
1668
1721
  }
1669
1722
  }
1670
1723
  }
1671
1724
  ```
1672
1725
 
1673
- When enabled, **all** write and delete operations proceed without user confirmation including destructive operations like `harness_delete`. Use with caution and consider pairing with `HARNESS_TOOLSETS` to restrict which resource types are available.
1726
+ > **Migration note:** `HARNESS_SKIP_ELICITATION=true` is still supported and maps to `HARNESS_AUTO_APPROVE_RISK=all`. A deprecation warning is logged to stderr. If both are set, `HARNESS_AUTO_APPROVE_RISK` takes precedence.
1727
+
1728
+ When set to `all`, **all** write and delete operations proceed without user confirmation — including destructive operations like `harness_delete`. Use with caution and consider pairing with `HARNESS_TOOLSETS` to restrict which resource types are available.
1674
1729
 
1675
1730
  ## Safety
1676
1731
 
1677
1732
  - **Secrets are never exposed.** The `secret` resource type returns metadata only (name, type, scope) — secret values are never included in any response.
1678
1733
  - **Write operations use elicitation when available.** `harness_create`, `harness_update`, `harness_delete`, and `harness_execute` attempt MCP elicitation before proceeding (see [Elicitation](#elicitation)).
1679
- - **Destructive writes fail closed.** If confirmation cannot be obtained, `harness_delete` is blocked instead of executing blindly. Override with `HARNESS_SKIP_ELICITATION=true` for autonomous workflows.
1734
+ - **Medium-risk and above fail closed.** If confirmation cannot be obtained for `medium_write`, `high_write`, or `destructive` operations, they are blocked instead of executing blindly. Override with `HARNESS_AUTO_APPROVE_RISK` for autonomous workflows.
1680
1735
  - **CORS restricted to same-origin.** The HTTP transport only allows same-origin requests, preventing CSRF attacks from malicious websites targeting the MCP server on localhost.
1681
1736
  - **HTTP rate limiting.** The HTTP transport enforces 60 requests per minute per IP to prevent request flooding.
1682
1737
  - **API rate limiting.** The Harness API client enforces a 10 requests/second limit to avoid hitting upstream rate limits.
@@ -0,0 +1,14 @@
1
+ import type { Config } from "../config.js";
2
+ import { AuditManager } from "./manager.js";
3
+ export { AuditManager } from "./manager.js";
4
+ export type { AuditEvent, AuditContext, AuditSink, ConfirmationMethod } from "./types.js";
5
+ /**
6
+ * Create an AuditManager with sinks enabled based on configuration.
7
+ *
8
+ * - StderrSink is always active
9
+ * - JsonlFileSink activates when HARNESS_AUDIT_FILE is set
10
+ * - WebhookSink activates when HARNESS_AUDIT_WEBHOOK_URL is set
11
+ * - OTelSink activates when @opentelemetry/api is importable + OTEL endpoint is set
12
+ */
13
+ export declare function createAuditManager(config: Config): AuditManager;
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/audit/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAO5C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAI1F;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAoC/D"}
@@ -0,0 +1,50 @@
1
+ import { AuditManager } from "./manager.js";
2
+ import { StderrSink } from "./sinks/stderr.js";
3
+ import { JsonlFileSink } from "./sinks/jsonl-file.js";
4
+ import { WebhookSink } from "./sinks/webhook.js";
5
+ import { OTelSink } from "./sinks/otel.js";
6
+ import { createLogger } from "../utils/logger.js";
7
+ export { AuditManager } from "./manager.js";
8
+ const log = createLogger("audit");
9
+ /**
10
+ * Create an AuditManager with sinks enabled based on configuration.
11
+ *
12
+ * - StderrSink is always active
13
+ * - JsonlFileSink activates when HARNESS_AUDIT_FILE is set
14
+ * - WebhookSink activates when HARNESS_AUDIT_WEBHOOK_URL is set
15
+ * - OTelSink activates when @opentelemetry/api is importable + OTEL endpoint is set
16
+ */
17
+ export function createAuditManager(config) {
18
+ const manager = new AuditManager();
19
+ manager.addSink(new StderrSink());
20
+ const auditFile = config.HARNESS_AUDIT_FILE;
21
+ if (auditFile) {
22
+ manager.addSink(new JsonlFileSink(auditFile));
23
+ log.info("JSONL audit file sink enabled", { path: auditFile });
24
+ }
25
+ const webhookUrl = config.HARNESS_AUDIT_WEBHOOK_URL;
26
+ if (webhookUrl) {
27
+ const token = config.HARNESS_AUDIT_WEBHOOK_TOKEN;
28
+ const batchSize = config.HARNESS_AUDIT_WEBHOOK_BATCH_SIZE;
29
+ const flushMs = config.HARNESS_AUDIT_WEBHOOK_FLUSH_MS;
30
+ manager.addSink(new WebhookSink({
31
+ url: webhookUrl,
32
+ token,
33
+ batchSize,
34
+ flushIntervalMs: flushMs,
35
+ }));
36
+ try {
37
+ const origin = new URL(webhookUrl).origin;
38
+ log.info("Webhook audit sink enabled", { host: origin });
39
+ }
40
+ catch {
41
+ log.info("Webhook audit sink enabled");
42
+ }
43
+ }
44
+ if (process.env.OTEL_EXPORTER_OTLP_ENDPOINT) {
45
+ manager.addSink(new OTelSink());
46
+ log.info("OTel audit sink enabled (pending @opentelemetry/api availability)");
47
+ }
48
+ return manager;
49
+ }
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/audit/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;AAElC;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,OAAO,GAAG,IAAI,YAAY,EAAE,CAAC;IAEnC,OAAO,CAAC,OAAO,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC;IAElC,MAAM,SAAS,GAAI,MAAkC,CAAC,kBAAwC,CAAC;IAC/F,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,OAAO,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9C,GAAG,CAAC,IAAI,CAAC,+BAA+B,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,UAAU,GAAI,MAAkC,CAAC,yBAA+C,CAAC;IACvG,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,KAAK,GAAI,MAAkC,CAAC,2BAAiD,CAAC;QACpG,MAAM,SAAS,GAAI,MAAkC,CAAC,gCAAsD,CAAC;QAC7G,MAAM,OAAO,GAAI,MAAkC,CAAC,8BAAoD,CAAC;QACzG,OAAO,CAAC,OAAO,CAAC,IAAI,WAAW,CAAC;YAC9B,GAAG,EAAE,UAAU;YACf,KAAK;YACL,SAAS;YACT,eAAe,EAAE,OAAO;SACzB,CAAC,CAAC,CAAC;QACJ,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC;YAC1C,GAAG,CAAC,IAAI,CAAC,4BAA4B,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,CAAC;QAC5C,OAAO,CAAC,OAAO,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;IAChF,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { AuditEvent, AuditSink } from "./types.js";
2
+ /**
3
+ * Fan-out orchestrator for audit events.
4
+ * Distributes each event to all registered sinks. Sink failures are
5
+ * logged but never propagate — audit must never break tool execution.
6
+ */
7
+ export declare class AuditManager {
8
+ private sinks;
9
+ addSink(sink: AuditSink): void;
10
+ emit(event: AuditEvent): void;
11
+ flush(): Promise<void>;
12
+ close(): Promise<void>;
13
+ }
14
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/audit/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAKxD;;;;GAIG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAmB;IAEhC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAK9B,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAevB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IActB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAc7B"}
@@ -0,0 +1,55 @@
1
+ import { createLogger } from "../utils/logger.js";
2
+ const log = createLogger("audit-manager");
3
+ /**
4
+ * Fan-out orchestrator for audit events.
5
+ * Distributes each event to all registered sinks. Sink failures are
6
+ * logged but never propagate — audit must never break tool execution.
7
+ */
8
+ export class AuditManager {
9
+ sinks = [];
10
+ addSink(sink) {
11
+ this.sinks.push(sink);
12
+ log.debug(`Audit sink registered: ${sink.name}`);
13
+ }
14
+ emit(event) {
15
+ for (const sink of this.sinks) {
16
+ try {
17
+ const result = sink.emit(event);
18
+ if (result && typeof result.catch === "function") {
19
+ result.catch((err) => {
20
+ log.warn(`Audit sink "${sink.name}" async emit failed`, { error: String(err) });
21
+ });
22
+ }
23
+ }
24
+ catch (err) {
25
+ log.warn(`Audit sink "${sink.name}" emit failed`, { error: String(err) });
26
+ }
27
+ }
28
+ }
29
+ async flush() {
30
+ await Promise.allSettled(this.sinks
31
+ .filter((s) => s.flush)
32
+ .map(async (s) => {
33
+ try {
34
+ await s.flush();
35
+ }
36
+ catch (err) {
37
+ log.warn(`Audit sink "${s.name}" flush failed`, { error: String(err) });
38
+ }
39
+ }));
40
+ }
41
+ async close() {
42
+ await this.flush();
43
+ await Promise.allSettled(this.sinks
44
+ .filter((s) => s.close)
45
+ .map(async (s) => {
46
+ try {
47
+ await s.close();
48
+ }
49
+ catch (err) {
50
+ log.warn(`Audit sink "${s.name}" close failed`, { error: String(err) });
51
+ }
52
+ }));
53
+ }
54
+ }
55
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/audit/manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,GAAG,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;AAE1C;;;;GAIG;AACH,MAAM,OAAO,YAAY;IACf,KAAK,GAAgB,EAAE,CAAC;IAEhC,OAAO,CAAC,IAAe;QACrB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,GAAG,CAAC,KAAK,CAAC,0BAA0B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,CAAC,KAAiB;QACpB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChC,IAAI,MAAM,IAAI,OAAQ,MAAwB,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;oBACnE,MAAwB,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;wBACtC,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,IAAI,qBAAqB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBAClF,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,IAAI,eAAe,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,OAAO,CAAC,UAAU,CACtB,IAAI,CAAC,KAAK;aACP,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;aACtB,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;YACf,IAAI,CAAC;gBACH,MAAM,CAAC,CAAC,KAAM,EAAE,CAAC;YACnB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,gBAAgB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC,CAAC,CACL,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,OAAO,CAAC,UAAU,CACtB,IAAI,CAAC,KAAK;aACP,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;aACtB,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;YACf,IAAI,CAAC;gBACH,MAAM,CAAC,CAAC,KAAM,EAAE,CAAC;YACnB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,gBAAgB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC,CAAC,CACL,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import type { AuditEvent, AuditSink } from "../types.js";
2
+ /**
3
+ * Appends audit events as NDJSON (one JSON object per line) to a file.
4
+ * Enabled when HARNESS_AUDIT_FILE is set.
5
+ */
6
+ export declare class JsonlFileSink implements AuditSink {
7
+ private readonly filePath;
8
+ readonly name = "jsonl-file";
9
+ private dirEnsured;
10
+ constructor(filePath: string);
11
+ emit(event: AuditEvent): void;
12
+ }
13
+ //# sourceMappingURL=jsonl-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-file.d.ts","sourceRoot":"","sources":["../../../src/audit/sinks/jsonl-file.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAKzD;;;GAGG;AACH,qBAAa,aAAc,YAAW,SAAS;IAIjC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAHrC,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,OAAO,CAAC,UAAU,CAAS;gBAEE,QAAQ,EAAE,MAAM;IAE7C,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAmB9B"}