@vibescope/mcp-server 0.3.3 → 0.3.4

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.
@@ -28,6 +28,7 @@ export * from './file-checkouts.js';
28
28
  export * from './roles.js';
29
29
  export * from './connectors.js';
30
30
  export * from './cloud-agents.js';
31
+ export * from './version.js';
31
32
  import type { HandlerRegistry } from './types.js';
32
33
  /**
33
34
  * Build the complete handler registry from all modules
@@ -28,6 +28,7 @@ export * from './file-checkouts.js';
28
28
  export * from './roles.js';
29
29
  export * from './connectors.js';
30
30
  export * from './cloud-agents.js';
31
+ export * from './version.js';
31
32
  import { milestoneHandlers } from './milestones.js';
32
33
  import { sessionHandlers } from './session.js';
33
34
  import { ideaHandlers } from './ideas.js';
@@ -51,6 +52,7 @@ import { fileCheckoutHandlers } from './file-checkouts.js';
51
52
  import { roleHandlers } from './roles.js';
52
53
  import { connectorHandlers } from './connectors.js';
53
54
  import { cloudAgentHandlers } from './cloud-agents.js';
55
+ import { versionHandlers } from './version.js';
54
56
  /**
55
57
  * Build the complete handler registry from all modules
56
58
  */
@@ -79,5 +81,6 @@ export function buildHandlerRegistry() {
79
81
  ...roleHandlers,
80
82
  ...connectorHandlers,
81
83
  ...cloudAgentHandlers,
84
+ ...versionHandlers,
82
85
  };
83
86
  }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Version management handlers
3
+ */
4
+ import type { HandlerRegistry } from './types.js';
5
+ export declare const versionHandlers: HandlerRegistry;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Version management handlers
3
+ */
4
+ import { execSync } from 'child_process';
5
+ import { success, error } from './types.js';
6
+ import { checkVersion, getLocalVersion } from '../version.js';
7
+ const PACKAGE_NAME = '@vibescope/mcp-server';
8
+ export const versionHandlers = {
9
+ check_mcp_version: async (_args, _ctx) => {
10
+ const info = await checkVersion();
11
+ if (info.error) {
12
+ return success({
13
+ current_version: info.current,
14
+ latest_version: info.latest,
15
+ update_available: false,
16
+ warning: info.error,
17
+ });
18
+ }
19
+ return success({
20
+ current_version: info.current,
21
+ latest_version: info.latest,
22
+ update_available: info.updateAvailable,
23
+ message: info.updateAvailable
24
+ ? `Update available! v${info.current} → v${info.latest}. Ask the user if they would like to update using the update_mcp_server tool.`
25
+ : `Vibescope MCP server is up to date (v${info.current}).`,
26
+ });
27
+ },
28
+ update_mcp_server: async (args, _ctx) => {
29
+ const useGlobal = args.global !== false; // default true
30
+ const flag = useGlobal ? '-g ' : '';
31
+ const command = `npm install ${flag}${PACKAGE_NAME}@latest`;
32
+ try {
33
+ const output = execSync(command, {
34
+ encoding: 'utf-8',
35
+ timeout: 60000,
36
+ stdio: ['pipe', 'pipe', 'pipe'],
37
+ });
38
+ // Check the new version
39
+ const newVersion = getLocalVersion();
40
+ return success({
41
+ updated: true,
42
+ command_run: command,
43
+ output: output.trim(),
44
+ new_version: newVersion,
45
+ message: 'Update complete. The MCP server must be restarted to use the new version. Please ask the user to restart their editor/MCP client, or reconnect the MCP server.',
46
+ });
47
+ }
48
+ catch (err) {
49
+ const message = err instanceof Error ? err.message : String(err);
50
+ return error(`Failed to update: ${message}. The user may need to run manually: ${command}`);
51
+ }
52
+ },
53
+ };
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ import { RateLimiter, getErrorMessage, } from './utils.js';
9
9
  import { buildHandlerRegistry } from './handlers/index.js';
10
10
  import { tools } from './tools/index.js';
11
11
  import { createTokenUsage, trackTokenUsage as trackTokens, } from './token-tracking.js';
12
+ import { getUpdateWarning } from './version.js';
12
13
  // ============================================================================
13
14
  // Agent Instance Tracking
14
15
  // ============================================================================
@@ -210,6 +211,11 @@ async function main() {
210
211
  console.error('Invalid API key');
211
212
  process.exit(1);
212
213
  }
214
+ // Check for updates (non-blocking, with timeout)
215
+ const updateWarning = await getUpdateWarning();
216
+ const serverInstructions = updateWarning
217
+ ? `${updateWarning}\n\nVibescope MCP server - AI project tracking and coordination tools.`
218
+ : 'Vibescope MCP server - AI project tracking and coordination tools.';
213
219
  const server = new Server({
214
220
  name: 'vibescope',
215
221
  version: '0.1.0',
@@ -217,6 +223,7 @@ async function main() {
217
223
  capabilities: {
218
224
  tools: {},
219
225
  },
226
+ instructions: serverInstructions,
220
227
  });
221
228
  // List available tools
222
229
  server.setRequestHandler(ListToolsRequestSchema, async () => {
@@ -30,6 +30,7 @@ import { sprintTools } from './sprints.js';
30
30
  import { gitIssueTools } from './git-issues.js';
31
31
  import { connectorTools } from './connectors.js';
32
32
  import { cloudAgentTools } from './cloud-agents.js';
33
+ import { versionTools } from './version.js';
33
34
  /**
34
35
  * All MCP tool definitions combined
35
36
  */
@@ -67,5 +68,6 @@ export declare const toolCategories: {
67
68
  readonly gitIssues: string[];
68
69
  readonly connectors: string[];
69
70
  readonly cloudAgents: string[];
71
+ readonly version: string[];
70
72
  };
71
- export { sessionTools, costTools, discoveryTools, worktreeTools, projectTools, taskTools, progressTools, blockerTools, decisionTools, ideaTools, findingTools, validationTools, deploymentTools, fallbackTools, requestTools, milestoneTools, bodiesOfWorkTools, organizationTools, fileCheckoutTools, roleTools, sprintTools, gitIssueTools, connectorTools, cloudAgentTools, };
73
+ export { sessionTools, costTools, discoveryTools, worktreeTools, projectTools, taskTools, progressTools, blockerTools, decisionTools, ideaTools, findingTools, validationTools, deploymentTools, fallbackTools, requestTools, milestoneTools, bodiesOfWorkTools, organizationTools, fileCheckoutTools, roleTools, sprintTools, gitIssueTools, connectorTools, cloudAgentTools, versionTools, };
@@ -29,6 +29,7 @@ import { sprintTools } from './sprints.js';
29
29
  import { gitIssueTools } from './git-issues.js';
30
30
  import { connectorTools } from './connectors.js';
31
31
  import { cloudAgentTools } from './cloud-agents.js';
32
+ import { versionTools } from './version.js';
32
33
  /**
33
34
  * All MCP tool definitions combined
34
35
  */
@@ -57,6 +58,7 @@ export const tools = [
57
58
  ...gitIssueTools,
58
59
  ...connectorTools,
59
60
  ...cloudAgentTools,
61
+ ...versionTools,
60
62
  ];
61
63
  /**
62
64
  * Build the complete tool list from all domain modules
@@ -93,6 +95,7 @@ export const toolCategories = {
93
95
  gitIssues: gitIssueTools.map((t) => t.name),
94
96
  connectors: connectorTools.map((t) => t.name),
95
97
  cloudAgents: cloudAgentTools.map((t) => t.name),
98
+ version: versionTools.map((t) => t.name),
96
99
  };
97
100
  // Re-export domain tools for selective imports
98
- export { sessionTools, costTools, discoveryTools, worktreeTools, projectTools, taskTools, progressTools, blockerTools, decisionTools, ideaTools, findingTools, validationTools, deploymentTools, fallbackTools, requestTools, milestoneTools, bodiesOfWorkTools, organizationTools, fileCheckoutTools, roleTools, sprintTools, gitIssueTools, connectorTools, cloudAgentTools, };
101
+ export { sessionTools, costTools, discoveryTools, worktreeTools, projectTools, taskTools, progressTools, blockerTools, decisionTools, ideaTools, findingTools, validationTools, deploymentTools, fallbackTools, requestTools, milestoneTools, bodiesOfWorkTools, organizationTools, fileCheckoutTools, roleTools, sprintTools, gitIssueTools, connectorTools, cloudAgentTools, versionTools, };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Version management tool definitions
3
+ */
4
+ import type { Tool } from './types.js';
5
+ export declare const versionTools: Tool[];
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Version management tool definitions
3
+ */
4
+ export const versionTools = [
5
+ {
6
+ name: 'check_mcp_version',
7
+ description: 'Check if the Vibescope MCP server is up to date. Compares the locally installed version against the latest published version on npm. Call this when starting a session or when the server instructions indicate an update is available.',
8
+ inputSchema: {
9
+ type: 'object',
10
+ properties: {},
11
+ required: [],
12
+ },
13
+ },
14
+ {
15
+ name: 'update_mcp_server',
16
+ description: 'Update the Vibescope MCP server to the latest version. Runs npm install to fetch the latest version. After updating, the server must be restarted (the agent should ask the user to restart their MCP client/editor). Only call this when the user agrees to update.',
17
+ inputSchema: {
18
+ type: 'object',
19
+ properties: {
20
+ global: {
21
+ type: 'boolean',
22
+ description: 'If true, update the global installation (npm install -g). If false, update locally. Default: true.',
23
+ },
24
+ },
25
+ required: [],
26
+ },
27
+ },
28
+ ];
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Version checking utilities
3
+ *
4
+ * Compares the locally installed version against the latest published
5
+ * version on npm to detect available updates.
6
+ */
7
+ export interface VersionInfo {
8
+ current: string;
9
+ latest: string | null;
10
+ updateAvailable: boolean;
11
+ error?: string;
12
+ }
13
+ /**
14
+ * Get the current locally installed version from package.json
15
+ */
16
+ export declare function getLocalVersion(): string;
17
+ /**
18
+ * Fetch the latest published version from npm registry
19
+ */
20
+ export declare function getLatestVersion(): Promise<string | null>;
21
+ /**
22
+ * Check if an update is available
23
+ */
24
+ export declare function checkVersion(): Promise<VersionInfo>;
25
+ /**
26
+ * Get the update warning message for server instructions, or null if up to date
27
+ */
28
+ export declare function getUpdateWarning(): Promise<string | null>;
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Version checking utilities
3
+ *
4
+ * Compares the locally installed version against the latest published
5
+ * version on npm to detect available updates.
6
+ */
7
+ import { readFileSync } from 'fs';
8
+ import { resolve, dirname } from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ const NPM_REGISTRY_URL = 'https://registry.npmjs.org/@vibescope/mcp-server';
11
+ const PACKAGE_NAME = '@vibescope/mcp-server';
12
+ /**
13
+ * Get the current locally installed version from package.json
14
+ */
15
+ export function getLocalVersion() {
16
+ try {
17
+ const __dirname = dirname(fileURLToPath(import.meta.url));
18
+ const pkgPath = resolve(__dirname, '..', 'package.json');
19
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
20
+ return pkg.version;
21
+ }
22
+ catch {
23
+ return 'unknown';
24
+ }
25
+ }
26
+ /**
27
+ * Fetch the latest published version from npm registry
28
+ */
29
+ export async function getLatestVersion() {
30
+ try {
31
+ const controller = new AbortController();
32
+ const timeout = setTimeout(() => controller.abort(), 5000);
33
+ const response = await fetch(`${NPM_REGISTRY_URL}/latest`, {
34
+ signal: controller.signal,
35
+ headers: { 'Accept': 'application/json' },
36
+ });
37
+ clearTimeout(timeout);
38
+ if (!response.ok)
39
+ return null;
40
+ const data = (await response.json());
41
+ return data.version ?? null;
42
+ }
43
+ catch {
44
+ return null;
45
+ }
46
+ }
47
+ /**
48
+ * Compare semver strings. Returns true if latest > current.
49
+ */
50
+ function isNewer(current, latest) {
51
+ const parse = (v) => v.split('.').map(Number);
52
+ const c = parse(current);
53
+ const l = parse(latest);
54
+ for (let i = 0; i < 3; i++) {
55
+ if ((l[i] ?? 0) > (c[i] ?? 0))
56
+ return true;
57
+ if ((l[i] ?? 0) < (c[i] ?? 0))
58
+ return false;
59
+ }
60
+ return false;
61
+ }
62
+ /**
63
+ * Check if an update is available
64
+ */
65
+ export async function checkVersion() {
66
+ const current = getLocalVersion();
67
+ const latest = await getLatestVersion();
68
+ if (!latest) {
69
+ return {
70
+ current,
71
+ latest: null,
72
+ updateAvailable: false,
73
+ error: 'Could not reach npm registry to check for updates',
74
+ };
75
+ }
76
+ return {
77
+ current,
78
+ latest,
79
+ updateAvailable: isNewer(current, latest),
80
+ };
81
+ }
82
+ /**
83
+ * Get the update warning message for server instructions, or null if up to date
84
+ */
85
+ export async function getUpdateWarning() {
86
+ const info = await checkVersion();
87
+ if (info.updateAvailable && info.latest) {
88
+ return `⚠️ UPDATE AVAILABLE: Vibescope MCP server v${info.current} is outdated. Latest version is v${info.latest}. Before starting work, inform the user that an update is available and recommend running the \`check_mcp_version\` tool, or ask them to update with: npm install -g ${PACKAGE_NAME}@latest (or npx @vibescope/mcp-server@latest for auto-update on next run).`;
89
+ }
90
+ return null;
91
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibescope/mcp-server",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "MCP server for Vibescope - AI project tracking tools",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -29,6 +29,7 @@ export * from './file-checkouts.js';
29
29
  export * from './roles.js';
30
30
  export * from './connectors.js';
31
31
  export * from './cloud-agents.js';
32
+ export * from './version.js';
32
33
 
33
34
  import type { HandlerRegistry } from './types.js';
34
35
  import { milestoneHandlers } from './milestones.js';
@@ -54,6 +55,7 @@ import { fileCheckoutHandlers } from './file-checkouts.js';
54
55
  import { roleHandlers } from './roles.js';
55
56
  import { connectorHandlers } from './connectors.js';
56
57
  import { cloudAgentHandlers } from './cloud-agents.js';
58
+ import { versionHandlers } from './version.js';
57
59
 
58
60
  /**
59
61
  * Build the complete handler registry from all modules
@@ -83,5 +85,6 @@ export function buildHandlerRegistry(): HandlerRegistry {
83
85
  ...roleHandlers,
84
86
  ...connectorHandlers,
85
87
  ...cloudAgentHandlers,
88
+ ...versionHandlers,
86
89
  };
87
90
  }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Version management handlers
3
+ */
4
+
5
+ import { execSync } from 'child_process';
6
+ import type { HandlerRegistry } from './types.js';
7
+ import { success, error } from './types.js';
8
+ import { checkVersion, getLocalVersion } from '../version.js';
9
+
10
+ const PACKAGE_NAME = '@vibescope/mcp-server';
11
+
12
+ export const versionHandlers: HandlerRegistry = {
13
+ check_mcp_version: async (_args, _ctx) => {
14
+ const info = await checkVersion();
15
+
16
+ if (info.error) {
17
+ return success({
18
+ current_version: info.current,
19
+ latest_version: info.latest,
20
+ update_available: false,
21
+ warning: info.error,
22
+ });
23
+ }
24
+
25
+ return success({
26
+ current_version: info.current,
27
+ latest_version: info.latest,
28
+ update_available: info.updateAvailable,
29
+ message: info.updateAvailable
30
+ ? `Update available! v${info.current} → v${info.latest}. Ask the user if they would like to update using the update_mcp_server tool.`
31
+ : `Vibescope MCP server is up to date (v${info.current}).`,
32
+ });
33
+ },
34
+
35
+ update_mcp_server: async (args, _ctx) => {
36
+ const useGlobal = args.global !== false; // default true
37
+ const flag = useGlobal ? '-g ' : '';
38
+ const command = `npm install ${flag}${PACKAGE_NAME}@latest`;
39
+
40
+ try {
41
+ const output = execSync(command, {
42
+ encoding: 'utf-8',
43
+ timeout: 60000,
44
+ stdio: ['pipe', 'pipe', 'pipe'],
45
+ });
46
+
47
+ // Check the new version
48
+ const newVersion = getLocalVersion();
49
+
50
+ return success({
51
+ updated: true,
52
+ command_run: command,
53
+ output: output.trim(),
54
+ new_version: newVersion,
55
+ message:
56
+ 'Update complete. The MCP server must be restarted to use the new version. Please ask the user to restart their editor/MCP client, or reconnect the MCP server.',
57
+ });
58
+ } catch (err) {
59
+ const message = err instanceof Error ? err.message : String(err);
60
+ return error(`Failed to update: ${message}. The user may need to run manually: ${command}`);
61
+ }
62
+ },
63
+ };
package/src/index.ts CHANGED
@@ -43,6 +43,7 @@ import {
43
43
  setCurrentModel,
44
44
  type TokenUsage,
45
45
  } from './token-tracking.js';
46
+ import { getUpdateWarning } from './version.js';
46
47
 
47
48
  // ============================================================================
48
49
  // Agent Instance Tracking
@@ -654,6 +655,13 @@ async function main() {
654
655
  process.exit(1);
655
656
  }
656
657
 
658
+ // Check for updates (non-blocking, with timeout)
659
+ const updateWarning = await getUpdateWarning();
660
+
661
+ const serverInstructions = updateWarning
662
+ ? `${updateWarning}\n\nVibescope MCP server - AI project tracking and coordination tools.`
663
+ : 'Vibescope MCP server - AI project tracking and coordination tools.';
664
+
657
665
  const server = new Server(
658
666
  {
659
667
  name: 'vibescope',
@@ -663,6 +671,7 @@ async function main() {
663
671
  capabilities: {
664
672
  tools: {},
665
673
  },
674
+ instructions: serverInstructions,
666
675
  }
667
676
  );
668
677
 
@@ -33,6 +33,7 @@ import { sprintTools } from './sprints.js';
33
33
  import { gitIssueTools } from './git-issues.js';
34
34
  import { connectorTools } from './connectors.js';
35
35
  import { cloudAgentTools } from './cloud-agents.js';
36
+ import { versionTools } from './version.js';
36
37
 
37
38
  /**
38
39
  * All MCP tool definitions combined
@@ -62,6 +63,7 @@ export const tools: Tool[] = [
62
63
  ...gitIssueTools,
63
64
  ...connectorTools,
64
65
  ...cloudAgentTools,
66
+ ...versionTools,
65
67
  ];
66
68
 
67
69
  /**
@@ -100,6 +102,7 @@ export const toolCategories = {
100
102
  gitIssues: gitIssueTools.map((t) => t.name),
101
103
  connectors: connectorTools.map((t) => t.name),
102
104
  cloudAgents: cloudAgentTools.map((t) => t.name),
105
+ version: versionTools.map((t) => t.name),
103
106
  } as const;
104
107
 
105
108
  // Re-export domain tools for selective imports
@@ -128,4 +131,5 @@ export {
128
131
  gitIssueTools,
129
132
  connectorTools,
130
133
  cloudAgentTools,
134
+ versionTools,
131
135
  };
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Version management tool definitions
3
+ */
4
+
5
+ import type { Tool } from './types.js';
6
+
7
+ export const versionTools: Tool[] = [
8
+ {
9
+ name: 'check_mcp_version',
10
+ description:
11
+ 'Check if the Vibescope MCP server is up to date. Compares the locally installed version against the latest published version on npm. Call this when starting a session or when the server instructions indicate an update is available.',
12
+ inputSchema: {
13
+ type: 'object' as const,
14
+ properties: {},
15
+ required: [],
16
+ },
17
+ },
18
+ {
19
+ name: 'update_mcp_server',
20
+ description:
21
+ 'Update the Vibescope MCP server to the latest version. Runs npm install to fetch the latest version. After updating, the server must be restarted (the agent should ask the user to restart their MCP client/editor). Only call this when the user agrees to update.',
22
+ inputSchema: {
23
+ type: 'object' as const,
24
+ properties: {
25
+ global: {
26
+ type: 'boolean',
27
+ description:
28
+ 'If true, update the global installation (npm install -g). If false, update locally. Default: true.',
29
+ },
30
+ },
31
+ required: [],
32
+ },
33
+ },
34
+ ];
package/src/version.ts ADDED
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Version checking utilities
3
+ *
4
+ * Compares the locally installed version against the latest published
5
+ * version on npm to detect available updates.
6
+ */
7
+
8
+ import { readFileSync } from 'fs';
9
+ import { resolve, dirname } from 'path';
10
+ import { fileURLToPath } from 'url';
11
+
12
+ const NPM_REGISTRY_URL = 'https://registry.npmjs.org/@vibescope/mcp-server';
13
+ const PACKAGE_NAME = '@vibescope/mcp-server';
14
+
15
+ export interface VersionInfo {
16
+ current: string;
17
+ latest: string | null;
18
+ updateAvailable: boolean;
19
+ error?: string;
20
+ }
21
+
22
+ /**
23
+ * Get the current locally installed version from package.json
24
+ */
25
+ export function getLocalVersion(): string {
26
+ try {
27
+ const __dirname = dirname(fileURLToPath(import.meta.url));
28
+ const pkgPath = resolve(__dirname, '..', 'package.json');
29
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
30
+ return pkg.version;
31
+ } catch {
32
+ return 'unknown';
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Fetch the latest published version from npm registry
38
+ */
39
+ export async function getLatestVersion(): Promise<string | null> {
40
+ try {
41
+ const controller = new AbortController();
42
+ const timeout = setTimeout(() => controller.abort(), 5000);
43
+
44
+ const response = await fetch(`${NPM_REGISTRY_URL}/latest`, {
45
+ signal: controller.signal,
46
+ headers: { 'Accept': 'application/json' },
47
+ });
48
+
49
+ clearTimeout(timeout);
50
+
51
+ if (!response.ok) return null;
52
+
53
+ const data = (await response.json()) as { version?: string };
54
+ return data.version ?? null;
55
+ } catch {
56
+ return null;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Compare semver strings. Returns true if latest > current.
62
+ */
63
+ function isNewer(current: string, latest: string): boolean {
64
+ const parse = (v: string) => v.split('.').map(Number);
65
+ const c = parse(current);
66
+ const l = parse(latest);
67
+
68
+ for (let i = 0; i < 3; i++) {
69
+ if ((l[i] ?? 0) > (c[i] ?? 0)) return true;
70
+ if ((l[i] ?? 0) < (c[i] ?? 0)) return false;
71
+ }
72
+ return false;
73
+ }
74
+
75
+ /**
76
+ * Check if an update is available
77
+ */
78
+ export async function checkVersion(): Promise<VersionInfo> {
79
+ const current = getLocalVersion();
80
+ const latest = await getLatestVersion();
81
+
82
+ if (!latest) {
83
+ return {
84
+ current,
85
+ latest: null,
86
+ updateAvailable: false,
87
+ error: 'Could not reach npm registry to check for updates',
88
+ };
89
+ }
90
+
91
+ return {
92
+ current,
93
+ latest,
94
+ updateAvailable: isNewer(current, latest),
95
+ };
96
+ }
97
+
98
+ /**
99
+ * Get the update warning message for server instructions, or null if up to date
100
+ */
101
+ export async function getUpdateWarning(): Promise<string | null> {
102
+ const info = await checkVersion();
103
+
104
+ if (info.updateAvailable && info.latest) {
105
+ return `⚠️ UPDATE AVAILABLE: Vibescope MCP server v${info.current} is outdated. Latest version is v${info.latest}. Before starting work, inform the user that an update is available and recommend running the \`check_mcp_version\` tool, or ask them to update with: npm install -g ${PACKAGE_NAME}@latest (or npx @vibescope/mcp-server@latest for auto-update on next run).`;
106
+ }
107
+
108
+ return null;
109
+ }