kubeview-mcp 1.7.0 → 1.7.1

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/CHANGELOG.md CHANGED
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.7.1] - 2026-03-07
11
+
12
+ ### Changed
13
+ - **Refactor publishing scripts and add tests for release workflow**
14
+ - **Enhance publish scripts and update README for clarity**
15
+ - **Update publish:mcp script in package.json to remove login requirement for mcp-publisher**
16
+ - **Refactor CLI run-command.js to simplify Kubernetes and Helm tool class handling**
17
+
10
18
  ## [1.7.0] - 2026-02-17
11
19
 
12
20
  ### Added
@@ -16,7 +24,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
16
24
  ### Changed
17
25
  - **Refactor CLI run-command.js to simplify Kubernetes and Helm tool class handling**
18
26
 
19
-
20
27
  ## [1.6.0] - 2026-02-04
21
28
 
22
29
  ### Changed
package/README.md CHANGED
@@ -1,29 +1,23 @@
1
1
  # KubeView MCP – Kubernetes Model Context Protocol Server
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/kubeview-mcp)](https://www.npmjs.com/package/kubeview-mcp)
3
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
5
  [![Node.js Version](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen)](https://nodejs.org/)
5
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.8+-blue)](https://www.typescriptlang.org/)
6
7
 
7
- **KubeView** is a read-only Model Context Protocol (MCP) server that enables AI agents (like Cursor IDE, Claude Code CLI, Codex CLI, Gemini CLI, etc.) to inspect, diagnose, and debug Kubernetes clusters safely. It provides a comprehensive set of tools for Kubernetes, Helm, Argo Workflows, and Argo CD.
8
- Learn more about the benefits of code mode and implementation in [Evicting MCP tool calls from your Kubernetes cluster](https://dev.to/mikhae1/evicting-mcp-tool-calls-from-your-kubernetes-cluster-428k).
8
+ **KubeView** is a read-only [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) server that lets AI agents (Cursor, Claude Code, Codex CLI, Gemini CLI, etc.) safely inspect, diagnose, and debug Kubernetes clusters. It covers Kubernetes core, Helm, Argo Workflows, and Argo CD.
9
9
 
10
- ---
11
-
12
- ## ✨ Features
13
-
14
- - **🧠 Code Mode**: Sandboxed TypeScript environment for complex reasoning and multi-step workflows.
15
- - **🛡️ Read-Only & Safe**: Designed for production safety with zero write access and sensitive data masking.
16
- - **☸️ Kubernetes Integration**: List/get resources, fetch metrics, stream logs and events, execute commands, and tools to diagnose network issues.
17
- - **📦 Helm Support (API-first)**: Inspect releases, values, manifests, and history via Kubernetes API first, with the CLI fallback.
18
- - **🐙 Argo Ecosystem**: Manage Argo Workflows and Argo CD applications using direct Kubernetes API or CLI.
10
+ > Read more: [Evicting MCP tool calls from your Kubernetes cluster](https://dev.to/mikhae1/evicting-mcp-tool-calls-from-your-kubernetes-cluster-428k)
19
11
 
20
12
  ---
21
13
 
22
- ## MCP SDK Compatibility
14
+ ## Features
23
15
 
24
- - This project is pinned to `@modelcontextprotocol/sdk@^1.25.3`.
25
- - Legacy loose type imports (`Tools`, `Prompts`, `Resources`, `Roots`, `Sampling`) are disallowed.
26
- - This compatibility pass intentionally excludes Streamable HTTP transport migration and icon metadata rollout.
16
+ - **🧠 Code Mode** Sandboxed TypeScript runtime for complex reasoning and multi-step workflows.
17
+ - **🛡️ Read-Only & Safe** Zero write access; sensitive data masking for production clusters.
18
+ - **☸️ Kubernetes** List/get resources, fetch metrics, stream logs and events, exec into containers, diagnose network issues.
19
+ - **📦 Helm (API-first)** – Inspect releases, values, manifests, and history via the Kubernetes API with CLI fallback.
20
+ - **🐙 Argo Ecosystem** – Manage Argo Workflows and Argo CD via the Kubernetes API or CLI.
27
21
 
28
22
  ---
29
23
 
@@ -33,21 +27,21 @@ Learn more about the benefits of code mode and implementation in [Evicting MCP t
33
27
 
34
28
  - Node.js ≥ 18
35
29
  - Access to a Kubernetes cluster
36
- - Optionally, CLIs installed in current $PATH: `helm` (fallback only), `argo`, `argocd`
30
+ - Optional CLIs in `$PATH`: `helm` (fallback only), `argo`, `argocd`
37
31
 
38
32
  ### Installation
39
33
 
40
34
  ```bash
41
- # start the server
35
+ # Run the server directly
42
36
  npx -y kubeview-mcp
43
37
 
44
- # install as a claude code mcp server
38
+ # Add to Claude Code
45
39
  claude mcp add kubernetes -- npx kubeview-mcp
46
40
  ```
47
41
 
48
- ### Configuration for MCP Clients
42
+ ### MCP Client Configuration
49
43
 
50
- Add to your `mcpServers` configuration (e.g., in Cursor or Claude Desktop):
44
+ Add to your `mcpServers` config (Cursor, Claude Desktop, etc.):
51
45
 
52
46
  ```json
53
47
  {
@@ -62,118 +56,94 @@ Add to your `mcpServers` configuration (e.g., in Cursor or Claude Desktop):
62
56
 
63
57
  ### Environment Variables
64
58
 
65
- Configure the server using environment variables:
66
-
67
59
  | Variable | Description | Default |
68
60
  | -------------------- | -------------------------------------------- | ---------------- |
69
61
  | `KUBECONFIG` | Path to kubeconfig file | `~/.kube/config` |
70
62
  | `MCP_MODE` | Server mode: `all`, `code`, or `tools` | `all` |
71
- | `MCP_LOG_LEVEL` | Log level (`error`, `warn`, `info`, `debug`) | `info` |
72
- | `MCP_HIDE_SENSITIVE` | Enable global sensitive data masking | `false` |
63
+ | `MCP_LOG_LEVEL` | Log level: `error`, `warn`, `info`, `debug` | `info` |
64
+ | `MCP_HIDE_SENSITIVE` | Mask sensitive data globally | `false` |
73
65
 
74
66
  ---
75
67
 
76
- ## 🛠️ Tools Overview
68
+ ## 🛠️ Tools
77
69
 
78
70
  ### Kubernetes
79
71
 
80
- - **`kube_list`**: List resources or get cluster diagnostics.
81
- - **`kube_get`**: Describe specific resources (supports all K8s types).
82
- - **`kube_metrics`**: Fetch CPU/memory metrics for nodes and pods.
83
- - **`kube_logs`**: Fetch or stream container logs.
84
- - **`kube_exec`**: Execute commands in containers (read-only recommended).
85
- - **`kube_port`**: Port-forward to pods/services.
86
- - **`kube_net`**: Run in-cluster network diagnostics.
72
+ | Tool | Description |
73
+ | -------------- | -------------------------------------------------------- |
74
+ | `kube_list` | List resources or get cluster diagnostics |
75
+ | `kube_get` | Describe a specific resource (all K8s types supported) |
76
+ | `kube_metrics` | Fetch CPU/memory metrics for nodes and pods |
77
+ | `kube_logs` | Fetch or stream container logs |
78
+ | `kube_exec` | Execute commands inside containers |
79
+ | `kube_port` | Port-forward to pods or services |
80
+ | `kube_net` | Run in-cluster network diagnostics |
87
81
 
88
82
  ### Helm
89
83
 
90
- - **`helm_list`**: List Helm releases (Kubernetes API first, CLI fallback).
91
- - **`helm_get`**: Fetch release values, manifests, notes, hooks, resources, status, and history (Kubernetes API first, CLI fallback).
92
-
93
- ### Helm Execution Strategy
84
+ | Tool | Description |
85
+ | ----------- | ----------------------------------------------------------------- |
86
+ | `helm_list` | List Helm releases (Kubernetes API first, CLI fallback) |
87
+ | `helm_get` | Fetch release values, manifests, notes, hooks, status, history |
94
88
 
95
- - Helm tools are **API-first by default** and read Helm release metadata from Kubernetes storage backends (Secrets and ConfigMaps).
96
- - Helm CLI is retained as a compatibility fallback path.
97
- - In normal read-only scenarios with Kubernetes API access, Helm operations do not require the `helm` binary.
98
- - If Helm is configured with a non-Kubernetes storage backend (for example SQL), CLI fallback may be required.
99
- - For `helm_get`/`helm_list`, JSON/default behavior uses API first; non-JSON formatting may use CLI fallback.
89
+ **Helm execution strategy:** Tools read Helm metadata directly from Kubernetes storage (Secrets / ConfigMaps) by default no `helm` binary needed for standard read-only use. CLI fallback is used for non-JSON formatting or non-Kubernetes storage backends (e.g. SQL).
100
90
 
101
91
  ### Argo
102
92
 
103
- - **`argo_list` / `argo_get`**: Manage Argo Workflows.
104
- - **`argocd_app`**: Inspect Argo CD applications and resources.
93
+ | Tool | Description |
94
+ | ------------- | ---------------------------------------- |
95
+ | `argo_list` | List Argo Workflows |
96
+ | `argo_get` | Inspect a specific Argo Workflow |
97
+ | `argocd_app` | Inspect Argo CD applications |
105
98
 
106
99
  ### Utilities
107
100
 
108
- - **`run_code`**: Execute sandboxed TypeScript code for complex tasks.
109
- - **`plan_step`**: Record step-by-step planning state for long, complex investigations.
101
+ | Tool | Description |
102
+ | ----------- | -------------------------------------------------------------- |
103
+ | `run_code` | Execute sandboxed TypeScript for complex tasks |
104
+ | `plan_step` | Persist step-by-step planning state across long investigations |
110
105
 
111
- ### Why `plan_step` really helps:
112
-
113
- 1. **Stable multi-step planning without bloating chat context.**
114
- Instead of dumping a massive plan into the conversation, the agent can store step-by-step progress in `plan_step` and keep user-facing responses clean.
115
- 2. **A consistent state machine for long tasks.**
116
- Complex workflows usually need: plan -> execute step 1 -> verify -> step 2 -> backtrack -> branch -> finalize. `plan_step` gives the agent a structured way to follow that lifecycle without losing track.
117
- 3. **Better tool routing.**
118
- Good agents alternate between thinking and acting. `plan_step` encourages that rhythm: log intent, call real tools, capture outcome, decide next step.
106
+ **Why `plan_step`?** It keeps the chat context clean by storing progress externally, gives agents a structured state machine (plan → execute → verify → branch), and encourages the think-then-act rhythm that produces better results on complex workflows.
119
107
 
120
108
  ---
121
109
 
122
110
  ## 🧠 Code Mode
123
111
 
124
- Inspired by [Code execution with MCP](https://www.anthropic.com/engineering/code-execution-with-mcp), KubeView ships with a code-mode runtime that allows agents to explore the API, search tools, and execute complex workflows in a sandboxed environment.
125
-
126
- ### What it provides
112
+ Inspired by [Code execution with MCP](https://www.anthropic.com/engineering/code-execution-with-mcp), KubeView ships a sandboxed code runtime for agents to explore the API and run complex workflows.
127
113
 
128
- - **MCP Bridge Layer**: Seamlessly connects to all registered MCP server tools.
129
- - **Dynamic TypeScript Definitions**: Automatically converts tool schemas into a strongly-typed `global.d.ts` resource, enabling agents to use valid TypeScript patterns and enjoy type safety without hallucinating parameters.
130
- - **Tool Search Utilities**: Runtime helpers like `tools.search()` and `tools.list()` allow agents to progressively discover capabilities without needing to load the entire schema context upfront.
131
- - **Sandboxed Execution**: A locked-down Node.js environment (via `vm`) with controlled access to the `console` and the `tools` global object, ensuring safe execution of agent-generated code.
114
+ - **MCP Bridge** All registered MCP tools are callable from within `run_code`.
115
+ - **Dynamic TypeScript Definitions** Tool schemas are auto-converted to a typed `global.d.ts`, preventing hallucinated parameters.
116
+ - **Tool Discovery** `tools.search()` and `tools.list()` let agents find capabilities at runtime without loading the full schema.
117
+ - **Sandboxed Execution** Locked-down Node.js `vm` environment with access only to `console` and the `tools` global.
132
118
 
133
- ### Usage
134
-
135
- For complex tasks requiring logic, loops, or data processing, use **Code Mode**:
119
+ Enable code-only mode:
136
120
 
137
121
  ```json
138
122
  "env": { "MCP_MODE": "code" }
139
123
  ```
140
124
 
141
- ### 💡 Pro Tip: `code-mode` MCP Prompt
142
-
143
- The server includes a built-in MCP server prompt named **`code-mode`** that injects the full TypeScript API documentation, tool overview, and examples into the context.
125
+ ### Built-in `code-mode` Prompt
144
126
 
145
- **In Cursor IDE**:
146
- Simply type `/kubeview/code-mode` in the prompt (or select it from the `/` prompt menu). This gives the AI the exact context it needs to write correct `run_code` scripts immediately.
127
+ The server includes a **`code-mode`** MCP prompt that injects full TypeScript API docs and examples into the agent context. In Cursor, type `/kubeview/code-mode` in the prompt bar to activate it.
147
128
 
148
129
  ---
149
130
 
150
131
  ## 💻 Local Development
151
132
 
152
- 1. **Clone & Install**:
153
-
154
- ```bash
155
- git clone https://github.com/mikhae1/kubeview-mcp.git
156
- cd kubeview-mcp
157
- npm install
158
- ```
159
-
160
- 2. **Build & Run**:
161
-
162
- ```bash
163
- npm run build
164
- npm start
165
- ```
166
-
167
- 3. **Test**:
168
- ```bash
169
- npm test
170
- ```
133
+ ```bash
134
+ # Clone and install
135
+ git clone https://github.com/mikhae1/kubeview-mcp.git
136
+ cd kubeview-mcp
137
+ npm install
171
138
 
172
- ### CLI Usage
139
+ # Build and run
140
+ npm run build
141
+ npm start
173
142
 
174
- You can test tools directly via the CLI:
143
+ # Test
144
+ npm test
175
145
 
176
- ```bash
146
+ # Run a tool directly via CLI
177
147
  npm run command -- kube_list --namespace=default
178
148
  ```
179
149
 
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env tsx
2
+ export {};
3
+ //# sourceMappingURL=publish-mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-mcp.d.ts","sourceRoot":"","sources":["../../scripts/publish-mcp.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env tsx
2
+ import { publishMcp } from './release-publish';
3
+ try {
4
+ publishMcp();
5
+ }
6
+ catch (error) {
7
+ console.error(error instanceof Error ? error.message : String(error));
8
+ process.exit(1);
9
+ }
10
+ //# sourceMappingURL=publish-mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-mcp.js","sourceRoot":"","sources":["../../scripts/publish-mcp.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,IAAI,CAAC;IACH,UAAU,EAAE,CAAC;AACf,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env tsx
2
+ type RunnerResult = {
3
+ status: number;
4
+ stdout: string;
5
+ stderr: string;
6
+ error?: NodeJS.ErrnoException;
7
+ };
8
+ type RunnerOptions = {
9
+ interactive?: boolean;
10
+ quiet?: boolean;
11
+ env?: NodeJS.ProcessEnv;
12
+ };
13
+ export type Runner = (command: string, args: string[], options?: RunnerOptions) => RunnerResult;
14
+ type PublishStep = 'all' | 'commit' | 'tag' | 'npm' | 'git' | 'mcp';
15
+ type PackageInfo = {
16
+ name: string;
17
+ version: string;
18
+ };
19
+ export declare function createRunner(options?: {
20
+ cwd?: string;
21
+ env?: NodeJS.ProcessEnv;
22
+ stdout?: Pick<NodeJS.WriteStream, 'write'>;
23
+ stderr?: Pick<NodeJS.WriteStream, 'write'>;
24
+ }): Runner;
25
+ export declare function publishMcp(options?: {
26
+ runner?: Runner;
27
+ cwd?: string;
28
+ }): 'published' | 'skipped';
29
+ export declare function runPublishWorkflow(options?: {
30
+ step?: PublishStep;
31
+ cwd?: string;
32
+ runner?: Runner;
33
+ packageInfo?: PackageInfo;
34
+ }): void;
35
+ export {};
36
+ //# sourceMappingURL=release-publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-publish.d.ts","sourceRoot":"","sources":["../../scripts/release-publish.ts"],"names":[],"mappings":";AAQA,KAAK,YAAY,GAAG;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAC/B,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,aAAa,KAAK,YAAY,CAAC;AAEhG,KAAK,WAAW,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEpE,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAWF,wBAAgB,YAAY,CAC1B,OAAO,GAAE;IACP,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CACvC,GACL,MAAM,CA+BR;AA6FD,wBAAgB,UAAU,CACxB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,WAAW,GAAG,SAAS,CAkCzB;AAoED,wBAAgB,kBAAkB,CAChC,OAAO,GAAE;IACP,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,CAAC;CACtB,GACL,IAAI,CAyBN"}
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env tsx
2
+ import { spawnSync } from 'child_process';
3
+ import { readFileSync } from 'fs';
4
+ import { join } from 'path';
5
+ const rootDir = process.cwd();
6
+ function readPackageInfo(cwd = rootDir) {
7
+ const packageJsonPath = join(cwd, 'package.json');
8
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
9
+ return {
10
+ name: packageJson.name,
11
+ version: packageJson.version,
12
+ };
13
+ }
14
+ export function createRunner(options = {}) {
15
+ const { cwd = rootDir, env = process.env, stdout = process.stdout, stderr = process.stderr, } = options;
16
+ return (command, args, commandOptions = {}) => {
17
+ const { interactive = false, quiet = false } = commandOptions;
18
+ const result = spawnSync(command, args, {
19
+ cwd,
20
+ env: { ...env, ...(commandOptions.env || {}) },
21
+ encoding: 'utf8',
22
+ stdio: interactive ? 'inherit' : 'pipe',
23
+ });
24
+ const normalized = {
25
+ status: result.status ?? (result.error ? 1 : 0),
26
+ stdout: typeof result.stdout === 'string' ? result.stdout : '',
27
+ stderr: typeof result.stderr === 'string' ? result.stderr : '',
28
+ error: result.error,
29
+ };
30
+ if (!interactive && !quiet) {
31
+ if (normalized.stdout)
32
+ stdout.write(normalized.stdout);
33
+ if (normalized.stderr)
34
+ stderr.write(normalized.stderr);
35
+ }
36
+ return normalized;
37
+ };
38
+ }
39
+ function formatCommand(command, args) {
40
+ return [command, ...args].join(' ');
41
+ }
42
+ function describeFailure(command, args, result) {
43
+ if (result.error?.code === 'ENOENT') {
44
+ return `Command not found: ${command}`;
45
+ }
46
+ const stderr = result.stderr.trim();
47
+ const stdout = result.stdout.trim();
48
+ const details = stderr || stdout;
49
+ return details
50
+ ? `${formatCommand(command, args)} failed: ${details}`
51
+ : `${formatCommand(command, args)} failed with exit code ${result.status}`;
52
+ }
53
+ function assertSuccess(command, args, result) {
54
+ if (result.status === 0 && !result.error) {
55
+ return result;
56
+ }
57
+ throw new Error(describeFailure(command, args, result));
58
+ }
59
+ function runCommand(runner, command, args, options) {
60
+ return runner(command, args, options);
61
+ }
62
+ function hasStagedChanges(runner) {
63
+ const result = runCommand(runner, 'git', ['diff', '--cached', '--quiet'], { quiet: true });
64
+ if (result.status === 0) {
65
+ return false;
66
+ }
67
+ if (result.status === 1) {
68
+ return true;
69
+ }
70
+ throw new Error(describeFailure('git', ['diff', '--cached', '--quiet'], result));
71
+ }
72
+ function getCurrentBranch(runner) {
73
+ const result = assertSuccess('git', ['rev-parse', '--abbrev-ref', 'HEAD'], runCommand(runner, 'git', ['rev-parse', '--abbrev-ref', 'HEAD'], { quiet: true }));
74
+ const branch = result.stdout.trim();
75
+ if (!branch || branch === 'HEAD') {
76
+ throw new Error('Refusing to publish from a detached HEAD');
77
+ }
78
+ return branch;
79
+ }
80
+ function tagExists(runner, tagName) {
81
+ const args = ['rev-parse', '-q', '--verify', `refs/tags/${tagName}`];
82
+ const result = runCommand(runner, 'git', args, { quiet: true });
83
+ if (result.status === 0) {
84
+ return true;
85
+ }
86
+ if (result.status === 1) {
87
+ return false;
88
+ }
89
+ throw new Error(describeFailure('git', args, result));
90
+ }
91
+ function npmVersionExists(runner, packageName, version) {
92
+ const result = runCommand(runner, 'npm', ['view', `${packageName}@${version}`, 'version'], {
93
+ quiet: true,
94
+ });
95
+ return result.status === 0;
96
+ }
97
+ function ensureNpmLogin(runner) {
98
+ const whoAmIResult = runCommand(runner, 'npm', ['whoami'], { quiet: true });
99
+ if (whoAmIResult.status === 0) {
100
+ return;
101
+ }
102
+ assertSuccess('npm', ['login'], runCommand(runner, 'npm', ['login'], { interactive: true }));
103
+ }
104
+ function isDuplicateMcpVersion(output) {
105
+ return output.includes('invalid version: cannot publish duplicate version');
106
+ }
107
+ export function publishMcp(options = {}) {
108
+ const runner = options.runner || createRunner({ cwd: options.cwd });
109
+ const attempts = [
110
+ ['mcp-publisher', ['publish', 'server.json']],
111
+ ['npx', ['-y', 'mcp-publisher', 'publish', 'server.json']],
112
+ ];
113
+ for (const [command, args] of attempts) {
114
+ const result = runCommand(runner, command, args, { quiet: true });
115
+ const output = `${result.stdout}\n${result.stderr}`;
116
+ if (result.stdout) {
117
+ process.stdout.write(result.stdout);
118
+ }
119
+ if (result.stderr) {
120
+ process.stderr.write(result.stderr);
121
+ }
122
+ if (result.status === 0 && !result.error) {
123
+ return 'published';
124
+ }
125
+ if (isDuplicateMcpVersion(output)) {
126
+ console.log('Version already published to MCP registry, skipping');
127
+ return 'skipped';
128
+ }
129
+ if (result.error?.code !== 'ENOENT') {
130
+ throw new Error(describeFailure(command, args, result));
131
+ }
132
+ }
133
+ throw new Error('Unable to publish to the MCP registry because neither `mcp-publisher` nor `npx mcp-publisher` is available');
134
+ }
135
+ function runCommit(runner, version) {
136
+ if (!hasStagedChanges(runner)) {
137
+ console.log('No staged changes, skipping commit');
138
+ return 'skipped';
139
+ }
140
+ assertSuccess('git', ['commit', '-m', `Release v${version}`], runCommand(runner, 'git', ['commit', '-m', `Release v${version}`], { interactive: true }));
141
+ return 'committed';
142
+ }
143
+ function runTag(runner, version) {
144
+ const tagName = `v${version}`;
145
+ if (tagExists(runner, tagName)) {
146
+ console.log(`Tag ${tagName} already exists, skipping`);
147
+ return 'skipped';
148
+ }
149
+ assertSuccess('git', ['tag', tagName], runCommand(runner, 'git', ['tag', tagName], { interactive: true }));
150
+ console.log(`Tagged version ${tagName}`);
151
+ return 'tagged';
152
+ }
153
+ function runNpmPublish(runner, packageName, version) {
154
+ if (npmVersionExists(runner, packageName, version)) {
155
+ console.log(`Version ${version} already published to npm, skipping`);
156
+ return 'skipped';
157
+ }
158
+ ensureNpmLogin(runner);
159
+ assertSuccess('npm', ['publish'], runCommand(runner, 'npm', ['publish'], { interactive: true }));
160
+ return 'published';
161
+ }
162
+ function runGitPush(runner) {
163
+ const branch = getCurrentBranch(runner);
164
+ assertSuccess('git', ['push', 'origin', branch, '--follow-tags'], runCommand(runner, 'git', ['push', 'origin', branch, '--follow-tags'], { interactive: true }));
165
+ return branch;
166
+ }
167
+ const stepHandlers = {
168
+ commit: ({ runner, packageInfo }) => runCommit(runner, packageInfo.version),
169
+ tag: ({ runner, packageInfo }) => runTag(runner, packageInfo.version),
170
+ npm: ({ runner, packageInfo }) => runNpmPublish(runner, packageInfo.name, packageInfo.version),
171
+ git: ({ runner }) => runGitPush(runner),
172
+ mcp: ({ runner, cwd }) => publishMcp({ runner, cwd }),
173
+ };
174
+ export function runPublishWorkflow(options = {}) {
175
+ const { step = 'all', cwd = rootDir, runner = createRunner({ cwd }), packageInfo = readPackageInfo(cwd), } = options;
176
+ const context = { cwd, runner, packageInfo };
177
+ if (step === 'all') {
178
+ stepHandlers.commit(context);
179
+ stepHandlers.tag(context);
180
+ stepHandlers.git(context);
181
+ stepHandlers.npm(context);
182
+ stepHandlers.mcp(context);
183
+ return;
184
+ }
185
+ const handler = stepHandlers[step];
186
+ if (!handler) {
187
+ throw new Error(`Unknown publish step: ${step}`);
188
+ }
189
+ handler(context);
190
+ }
191
+ const invokedPath = process.argv[1] || '';
192
+ const isDirectRun = invokedPath.endsWith('/scripts/release-publish.ts') ||
193
+ invokedPath.endsWith('\\scripts\\release-publish.ts') ||
194
+ invokedPath.endsWith('/scripts/release-publish.js') ||
195
+ invokedPath.endsWith('\\scripts\\release-publish.js');
196
+ if (isDirectRun) {
197
+ try {
198
+ const step = process.argv[2] || 'all';
199
+ runPublishWorkflow({ step });
200
+ }
201
+ catch (error) {
202
+ console.error(error instanceof Error ? error.message : String(error));
203
+ process.exit(1);
204
+ }
205
+ }
206
+ //# sourceMappingURL=release-publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-publish.js","sourceRoot":"","sources":["../../scripts/release-publish.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "1.7.0";
1
+ export declare const VERSION = "1.7.1";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // Auto-generated by scripts/build-version.js - DO NOT EDIT
2
- export const VERSION = '1.7.0';
2
+ export const VERSION = '1.7.1';
3
3
  //# sourceMappingURL=version.js.map
@@ -0,0 +1,7 @@
1
+ type CommandResult = {
2
+ status: number;
3
+ stdout?: string;
4
+ stderr?: string;
5
+ error?: NodeJS.ErrnoException;
6
+ };
7
+ //# sourceMappingURL=PublishWorkflow.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PublishWorkflow.test.d.ts","sourceRoot":"","sources":["../../../tests/release/PublishWorkflow.test.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GAAG;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAC/B,CAAC"}
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ describe('release publish workflow', () => {
3
+ let publishMcp;
4
+ let runPublishWorkflow;
5
+ const packageInfo = {
6
+ name: 'kubeview-mcp',
7
+ version: '1.7.0',
8
+ };
9
+ beforeAll(async () => {
10
+ const module = await import('../../scripts/release-publish');
11
+ publishMcp = module.publishMcp;
12
+ runPublishWorkflow = module.runPublishWorkflow;
13
+ });
14
+ function createRunner(handler) {
15
+ return jest.fn((command, args) => {
16
+ const result = handler(command, args);
17
+ return {
18
+ status: result.status,
19
+ stdout: result.stdout ?? '',
20
+ stderr: result.stderr ?? '',
21
+ error: result.error,
22
+ };
23
+ });
24
+ }
25
+ it('creates the tag before pushing during publish:all', () => {
26
+ const runner = createRunner((command, args) => {
27
+ if (command === 'git' && args.join(' ') === 'diff --cached --quiet') {
28
+ return { status: 1 };
29
+ }
30
+ if (command === 'git' && args.join(' ') === 'rev-parse -q --verify refs/tags/v1.7.0') {
31
+ return { status: 1 };
32
+ }
33
+ if (command === 'git' && args.join(' ') === 'rev-parse --abbrev-ref HEAD') {
34
+ return { status: 0, stdout: 'release/main\n' };
35
+ }
36
+ if (command === 'npm' && args.join(' ') === 'view kubeview-mcp@1.7.0 version') {
37
+ return { status: 1 };
38
+ }
39
+ if (command === 'npm' && args.join(' ') === 'whoami') {
40
+ return { status: 0, stdout: 'mikhae1\n' };
41
+ }
42
+ return { status: 0 };
43
+ });
44
+ const logSpy = jest.spyOn(console, 'log').mockImplementation(() => undefined);
45
+ runPublishWorkflow({ runner, packageInfo, step: 'all' });
46
+ const executedCommands = runner.mock.calls.map(([command, args]) => `${command} ${args.join(' ')}`);
47
+ expect(executedCommands).toEqual([
48
+ 'git diff --cached --quiet',
49
+ 'git commit -m Release v1.7.0',
50
+ 'git rev-parse -q --verify refs/tags/v1.7.0',
51
+ 'git tag v1.7.0',
52
+ 'git rev-parse --abbrev-ref HEAD',
53
+ 'git push origin release/main --follow-tags',
54
+ 'npm view kubeview-mcp@1.7.0 version',
55
+ 'npm whoami',
56
+ 'npm publish',
57
+ 'mcp-publisher publish server.json',
58
+ ]);
59
+ expect(logSpy).toHaveBeenCalledWith('Tagged version v1.7.0');
60
+ });
61
+ it('skips the commit step when nothing is staged', () => {
62
+ const runner = createRunner((command, args) => {
63
+ if (command === 'git' && args.join(' ') === 'diff --cached --quiet') {
64
+ return { status: 0 };
65
+ }
66
+ return { status: 0 };
67
+ });
68
+ const logSpy = jest.spyOn(console, 'log').mockImplementation(() => undefined);
69
+ runPublishWorkflow({ runner, packageInfo, step: 'commit' });
70
+ expect(logSpy).toHaveBeenCalledWith('No staged changes, skipping commit');
71
+ expect(runner).toHaveBeenCalledTimes(1);
72
+ });
73
+ it('falls back to npx for MCP publish and treats duplicate versions as success', () => {
74
+ const stdoutSpy = jest.spyOn(process.stdout, 'write').mockImplementation(() => true);
75
+ const stderrSpy = jest.spyOn(process.stderr, 'write').mockImplementation(() => true);
76
+ const logSpy = jest.spyOn(console, 'log').mockImplementation(() => undefined);
77
+ const runner = createRunner((command, args) => {
78
+ if (command === 'mcp-publisher') {
79
+ return {
80
+ status: 1,
81
+ error: Object.assign(new Error('not found'), { code: 'ENOENT' }),
82
+ };
83
+ }
84
+ if (command === 'npx' && args.join(' ') === '-y mcp-publisher publish server.json') {
85
+ return {
86
+ status: 1,
87
+ stderr: 'invalid version: cannot publish duplicate version',
88
+ };
89
+ }
90
+ throw new Error(`Unexpected command: ${command} ${args.join(' ')}`);
91
+ });
92
+ const result = publishMcp({ runner });
93
+ expect(result).toBe('skipped');
94
+ expect(runner).toHaveBeenNthCalledWith(1, 'mcp-publisher', ['publish', 'server.json'], {
95
+ quiet: true,
96
+ });
97
+ expect(runner).toHaveBeenNthCalledWith(2, 'npx', ['-y', 'mcp-publisher', 'publish', 'server.json'], { quiet: true });
98
+ expect(stderrSpy).toHaveBeenCalledWith('invalid version: cannot publish duplicate version');
99
+ expect(logSpy).toHaveBeenCalledWith('Version already published to MCP registry, skipping');
100
+ expect(stdoutSpy).not.toHaveBeenCalled();
101
+ });
102
+ });
103
+ //# sourceMappingURL=PublishWorkflow.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PublishWorkflow.test.js","sourceRoot":"","sources":["../../../tests/release/PublishWorkflow.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kubeview-mcp",
3
- "version": "1.7.0",
3
+ "version": "1.7.1",
4
4
  "description": "Read-only MCP server enabling code-driven AI analysis of Kubernetes clusters",
5
5
  "homepage": "https://github.com/mikhae1/kubeview-mcp",
6
6
  "mcpName": "io.github.mikhae1/kubeview",
@@ -39,12 +39,13 @@
39
39
  "release:build": "npm run build",
40
40
  "release:version": "node scripts/update-version.js && node scripts/build-version.js",
41
41
  "release": "npm run release:qa && npm run release:version && npm run release:build",
42
- "publish:commit": "git commit -m 'Release v$(node -p \"require('./package.json').version\")' || echo 'Commit failed'",
43
- "publish:tag": "VERSION=$(node -p \"require('./package.json').version\") && if git rev-parse \"v$VERSION\" >/dev/null 2>&1; then echo \"Tag v$VERSION already exists, skipping\"; else git tag \"v$VERSION\" && echo \"Tagged version v$VERSION\"; fi",
44
- "publish:npm": "VERSION=$(node -p \"require('./package.json').version\") && if npm view \"$npm_package_name@$VERSION\" version >/dev/null 2>&1; then echo \"Version $VERSION already published, skipping npm publish\"; else npm whoami >/dev/null 2>&1 || npm login; npm publish; fi",
45
- "publish:git": "git push origin master --tags",
46
- "publish:mcp": "mcp-publisher login github && mcp-publisher publish server.json",
47
- "publish": "npm run publish:commit && npm run publish:npm && npm run publish:git && npm run publish:mcp"
42
+ "publish:commit": "tsx scripts/release-publish.ts commit",
43
+ "publish:tag": "tsx scripts/release-publish.ts tag",
44
+ "publish:npm": "tsx scripts/release-publish.ts npm",
45
+ "publish:git": "tsx scripts/release-publish.ts git",
46
+ "publish:mcp": "tsx scripts/publish-mcp.ts",
47
+ "publish:all": "tsx scripts/release-publish.ts all",
48
+ "release:publish": "npm run publish:all"
48
49
  },
49
50
  "keywords": [
50
51
  "kubernetes",