Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ Register the skill directory in your AI client to get optimal tool usage guidanc
195. `list_group_iterations` - List group iterations with filtering options
196. `upload_markdown` - Upload a file for use in markdown content
197. `download_attachment` - Download an uploaded file from a project (images returned as base64; use local_path to save to disk)
198. `health_check` - Verify server status and authentication. When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted.
198. `health_check` - Verify server status and authentication. Always reports the MCP server version (mcp_server_version). When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted.
199. `list_events` - List events for the authenticated user (before/after: YYYY-MM-DD)
200. `get_project_events` - List events for a project (before/after: YYYY-MM-DD)
201. `list_releases` - List all releases for a project
Expand Down
2 changes: 1 addition & 1 deletion docs/tools/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Project/namespace listing, member queries, group iterations, and server health.
| [`verify_namespace`](projects.md#verify_namespace) | Verify if a namespace path exists. Use parent_id to scope the check to a specific parent namespace — required for nested namespaces where the same path may exist under different parents. | 📖 |
| [`list_group_projects`](projects.md#list_group_projects) | List projects in a group. Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented. | 📖 |
| [`list_group_iterations`](projects.md#list_group_iterations) | List group iterations with filtering options. Use this for a collection of resources; choose the corresponding get tool when you already know the single resource to inspect. It is read-only and does not mutate GitLab data; missing resources, invalid identifiers, insufficient permission, and rate limits are returned as errors. When `project_id` or `group_id` is accepted, provide the numeric ID or complete URL-encoded path described by the schema; use required identifiers and pagination fields exactly as documented. | 📖 |
| [`health_check`](projects.md#health_check) | Verify server status and authentication. When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted. Use this to verify server connectivity and authentication before making GitLab requests; use `whoami` when the authenticated user's identity is the goal. It does not mutate GitLab state and returns server/authentication status plus GitLab version details when available. | 📖 |
| [`health_check`](projects.md#health_check) | Verify server status and authentication. Always reports the MCP server version (mcp_server_version). When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted. Use this to verify server connectivity and authentication before making GitLab requests; use `whoami` when the authenticated user's identity is the goal. It does not mutate GitLab state and returns server/authentication status plus GitLab version details when available. | 📖 |

### [Projects & Files](repositories.md)

Expand Down
2 changes: 1 addition & 1 deletion docs/tools/projects.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ List group iterations with filtering options. Use this for a collection of resou

*📖 Read-only*

Verify server status and authentication. When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted. Use this to verify server connectivity and authentication before making GitLab requests; use `whoami` when the authenticated user's identity is the goal. It does not mutate GitLab state and returns server/authentication status plus GitLab version details when available.
Verify server status and authentication. Always reports the MCP server version (mcp_server_version). When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted. Use this to verify server connectivity and authentication before making GitLab requests; use `whoami` when the authenticated user's identity is the goal. It does not mutate GitLab state and returns server/authentication status plus GitLab version details when available.

**Parameters**

Expand Down
2 changes: 2 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14090,6 +14090,7 @@ async function handleToolCall(params: any) {
status: authenticated ? "ok" : "error",
authenticated,
gitlab_url: getEffectiveApiUrl(),
mcp_server_version: SERVER_VERSION,
...(versionMetadata ?? {}),
}),
},
Expand Down Expand Up @@ -15643,6 +15644,7 @@ async function startStreamableHTTPServer(): Promise<void> {
}
res.status(isHealthy ? 200 : 503).json({
status: isHealthy ? "healthy" : "degraded",
version: SERVER_VERSION,
activeSessions,
maxSessions: MAX_SESSIONS,
uptime: process.uptime(),
Expand Down
10 changes: 10 additions & 0 deletions test/streamable-http-concurrent-session.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { after, before, describe, test } from "node:test";
import assert from "node:assert";
import { Buffer } from "node:buffer";
import fs from "node:fs";
import path, { dirname } from "node:path";
import { fileURLToPath } from "node:url";
import {
cleanupServers,
findAvailablePort,
Expand All @@ -15,6 +18,11 @@ import { CustomHeaderClient } from "./clients/custom-header-client.js";
const MOCK_TOKEN = "mock-concurrent-token-12345";
const TEST_PROJECT_ID = "123";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const packageJsonPath = path.resolve(__dirname, "../package.json");
const PACKAGE_VERSION = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")).version;

function fileResponse(filePath: string, content: string) {
return {
file_name: filePath.split("/").at(-1),
Expand Down Expand Up @@ -176,12 +184,14 @@ describe("Streamable HTTP health check capacity logging", { timeout: 20_000 }, (
const response = await fetch(`${baseUrl}/health`);
const body = (await response.json()) as {
status: string;
version: string;
activeSessions: number;
maxSessions: number;
};

assert.strictEqual(response.status, 503);
assert.strictEqual(body.status, "degraded");
assert.strictEqual(body.version, PACKAGE_VERSION);
assert.strictEqual(body.activeSessions, 1);
assert.strictEqual(body.maxSessions, 1);

Expand Down
10 changes: 10 additions & 0 deletions test/test-health-check.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { describe, test, before, after } from "node:test";
import assert from "node:assert";
import { spawn } from "child_process";
import fs from "node:fs";
import path, { dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { MockGitLabServer, findMockServerPort } from "./utils/mock-gitlab-server.js";

const MOCK_TOKEN = "glpat-mock-token-12345";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const packageJsonPath = path.resolve(__dirname, "../package.json");
const PACKAGE_VERSION = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")).version;

function createMockGitLabServer(port: number): MockGitLabServer {
return new MockGitLabServer({
port,
Expand Down Expand Up @@ -88,6 +96,7 @@ describe("When health_check runs", () => {

assert.equal(result.status, "ok");
assert.equal(result.authenticated, true);
assert.equal(result.mcp_server_version, PACKAGE_VERSION);
assert.equal(result.version, "18.3.1-ee");
assert.equal(result.revision, "abc1234");
assert.equal(result.enterprise, true);
Expand All @@ -111,6 +120,7 @@ describe("When health_check runs", () => {

assert.equal(result.status, "ok");
assert.equal(result.authenticated, true);
assert.equal(result.mcp_server_version, PACKAGE_VERSION);
assert.equal("version" in result, false);
assert.equal("revision" in result, false);
assert.equal("enterprise" in result, false);
Expand Down
2 changes: 1 addition & 1 deletion tools/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1193,7 +1193,7 @@ export const allTools = [
{
name: "health_check",
description:
"Verify server status and authentication. When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted.",
"Verify server status and authentication. Always reports the MCP server version (mcp_server_version). When authenticated, also reports the GitLab instance version from GET /api/v4/version (version, revision, enterprise). Version lookup failures do not fail the health check — those fields are omitted.",
inputSchema: toJSONSchema(HealthCheckSchema),
},
{
Expand Down
Loading