Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 3 additions & 18 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,9 @@ import fs from "node:fs";
import { pipeline as streamPipeline } from "node:stream/promises";
import os from "node:os";
import nodeFetch from "node-fetch";
import path, { dirname } from "node:path";
import path from "node:path";
import { CookieJar, parse as parseCookie } from "tough-cookie";
import { fileURLToPath, URL } from "node:url";
import { URL } from "node:url";
import { z } from "zod";

import { initializeOAuthClient, GitLabOAuth } from "./oauth.js";
Expand All @@ -199,6 +199,7 @@ import { mcpAuthRouter } from "@modelcontextprotocol/sdk/server/auth/router.js";
import { ipKeyGenerator } from "express-rate-limit";
import { normalizeProxyClientIpForRateLimit } from "./utils/proxy-client-ip.js";
import { getForwardedPublicBaseUrl } from "./utils/forwarded-public-base-url.js";
import { SERVER_VERSION } from "./server/version.js";
import { normalizeGitLabApiUrl } from "./utils/url.js";
import {
estimateMergeCommitCount,
Expand Down Expand Up @@ -623,22 +624,6 @@ enum TransportMode {
STREAMABLE_HTTP = "streamable-http",
}

/**
* Read version from package.json
*/
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const packageJsonPath = path.resolve(__dirname, "../package.json");
let SERVER_VERSION = "unknown";
try {
if (fs.existsSync(packageJsonPath)) {
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
SERVER_VERSION = packageJson.version || SERVER_VERSION;
}
} catch {
// Intentionally ignored: version read failure is non-critical
}

/**
* Create a new MCP Server instance with request handlers registered.
* Each transport connection gets its own Server instance to prevent
Expand Down
27 changes: 27 additions & 0 deletions server/version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import fs from "node:fs";
import path, { dirname } from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const packageJsonPaths = [
// Built file: build/server/version.js -> ../../package.json
path.resolve(__dirname, "../../package.json"),
// Source file under tsx/node:test: server/version.ts -> ../package.json
path.resolve(__dirname, "../package.json"),
];
Comment on lines +8 to +13

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Potentially resolves the wrong package.json in source runs.

At Line 10, ../../package.json is tried before the source-local candidate. When running from server/version.ts, this can pick a parent workspace package.json and report an incorrect SERVER_VERSION.

Suggested fix
 const packageJsonPaths = [
-  // Built file: build/server/version.js -> ../../package.json
-  path.resolve(__dirname, "../../package.json"),
   // Source file under tsx/node:test: server/version.ts -> ../package.json
   path.resolve(__dirname, "../package.json"),
+  // Built file: build/server/version.js -> ../../package.json
+  path.resolve(__dirname, "../../package.json"),
 ];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const packageJsonPaths = [
// Built file: build/server/version.js -> ../../package.json
path.resolve(__dirname, "../../package.json"),
// Source file under tsx/node:test: server/version.ts -> ../package.json
path.resolve(__dirname, "../package.json"),
];
const packageJsonPaths = [
// Source file under tsx/node:test: server/version.ts -> ../package.json
path.resolve(__dirname, "../package.json"),
// Built file: build/server/version.js -> ../../package.json
path.resolve(__dirname, "../../package.json"),
];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/version.ts` around lines 8 - 13, The packageJsonPaths array in the
version.ts file tries to resolve the built file path before the source file
path. When running from source, this can incorrectly resolve to a parent
workspace's package.json. Reorder the paths in the packageJsonPaths array so
that the source-local path (the one using ../package.json relative to __dirname)
is attempted first, followed by the built file path (../../package.json),
ensuring that source runs pick up the correct package.json before falling back
to the built location.


export const SERVER_VERSION: string = (() => {
for (const packageJsonPath of packageJsonPaths) {
try {
if (fs.existsSync(packageJsonPath)) {
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
return packageJson.version || "unknown";
}
} catch {
// Intentionally ignored: version read failure is non-critical.
}
}
return "unknown";
})();
10 changes: 10 additions & 0 deletions test/server/version.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { test } from "node:test";
import assert from "node:assert";
import fs from "node:fs";
import { SERVER_VERSION } from "../../server/version.js";

const packageVersion = JSON.parse(fs.readFileSync("package.json", "utf8")).version;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Make the fixture path independent of process CWD.

At Line 6, reading "package.json" relative to process.cwd() makes this test flaky when invoked from another directory.

Suggested fix
-const packageVersion = JSON.parse(fs.readFileSync("package.json", "utf8")).version;
+const packageJsonUrl = new URL("../../package.json", import.meta.url);
+const packageVersion = JSON.parse(fs.readFileSync(packageJsonUrl, "utf8")).version;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const packageVersion = JSON.parse(fs.readFileSync("package.json", "utf8")).version;
const packageJsonUrl = new URL("../../package.json", import.meta.url);
const packageVersion = JSON.parse(fs.readFileSync(packageJsonUrl, "utf8")).version;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/server/version.test.ts` at line 6, The packageVersion constant is
reading package.json using a relative path which depends on the process current
working directory, making the test flaky when run from different directories.
Instead, construct an absolute path to package.json using __dirname (the
directory of the current test file) and the path module to navigate to the
project root where package.json is located. Replace the relative "package.json"
string in the fs.readFileSync call with this absolute path so the test can find
the file regardless of which directory the test is invoked from.


test("SERVER_VERSION matches package.json", () => {
assert.strictEqual(SERVER_VERSION, packageVersion);
});
Comment thread
cursor[bot] marked this conversation as resolved.
Loading