From 8655a8d36616fab31096bc822965183e1e2766cf Mon Sep 17 00:00:00 2001 From: coderyaz856 Date: Mon, 14 Sep 2026 22:30:14 +0100 Subject: [PATCH] Report the package version in the MCP client handshake --- bin/mantis.js | 10 +-------- lib/impl/mcp-client-service.js | 3 ++- lib/utils/package-root.js | 5 +++++ test/mcp-client-service.test.js | 40 +++++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 test/mcp-client-service.test.js diff --git a/bin/mantis.js b/bin/mantis.js index c214d26..fa72bf9 100644 --- a/bin/mantis.js +++ b/bin/mantis.js @@ -1,6 +1,5 @@ #!/usr/bin/env node -import fs from 'node:fs'; import path from 'node:path'; import { Command } from 'commander'; @@ -12,14 +11,7 @@ import { getContainer } from '../lib/container.js'; import { parseUseCommand } from '../lib/utils/tool-args.js'; -import { PACKAGE_ROOT } from '../lib/utils/package-root.js'; - - - -// single source of truth for the version: package.json (never hardcode) -const { version: VERSION } = JSON.parse( - fs.readFileSync(path.join(PACKAGE_ROOT, 'package.json'), 'utf8'), -); +import { PACKAGE_VERSION as VERSION } from '../lib/utils/package-root.js'; const c = getContainer(); diff --git a/lib/impl/mcp-client-service.js b/lib/impl/mcp-client-service.js index 472827c..1652947 100644 --- a/lib/impl/mcp-client-service.js +++ b/lib/impl/mcp-client-service.js @@ -1,6 +1,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'; +import { PACKAGE_VERSION } from '../utils/package-root.js'; import { mcpUrl } from '../utils/url.js'; export class McpClientService { @@ -24,7 +25,7 @@ export class McpClientService { const transport = new StreamableHTTPClientTransport(new URL(mcpUrl(cfg)), { requestInit: { headers: this._headers(cfg) }, }); - const client = new Client({ name: 'mantisai-cli', version: '3.1.0' }); + const client = new Client({ name: 'mantisai-cli', version: PACKAGE_VERSION }); await client.connect(transport); try { return await fn(client); diff --git a/lib/utils/package-root.js b/lib/utils/package-root.js index 346aa9a..50672e0 100644 --- a/lib/utils/package-root.js +++ b/lib/utils/package-root.js @@ -19,3 +19,8 @@ function findPackageRoot(start) { export const PACKAGE_ROOT = findPackageRoot(__dirname); export const SKILLS_DIR = path.join(PACKAGE_ROOT, 'skills'); + +// single source of truth for the version: package.json (never hardcode) +export const PACKAGE_VERSION = JSON.parse( + fs.readFileSync(path.join(PACKAGE_ROOT, 'package.json'), 'utf8'), +).version; diff --git a/test/mcp-client-service.test.js b/test/mcp-client-service.test.js new file mode 100644 index 0000000..54f27f9 --- /dev/null +++ b/test/mcp-client-service.test.js @@ -0,0 +1,40 @@ +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import http from 'node:http'; +import test from 'node:test'; + +import { McpClientService } from '../lib/impl/mcp-client-service.js'; + +const { version: packageVersion } = JSON.parse( + fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8'), +); + +test('MCP handshake reports the package.json version', async (t) => { + // Stand-in MCP endpoint: records the initialize request, then refuses it. + let clientInfo; + const server = http.createServer((req, res) => { + let body = ''; + req.on('data', (chunk) => { body += chunk; }); + req.on('end', () => { + try { + const messages = [].concat(JSON.parse(body)); + clientInfo ??= messages.find((m) => m.method === 'initialize')?.params?.clientInfo; + } catch { /* not JSON */ } + res.writeHead(401, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ error: 'refused by test server' })); + }); + }); + await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); + t.after(() => new Promise((resolve) => server.close(resolve))); + + const mcp = new McpClientService({ + requireAuth: () => ({ + apiBaseUrl: `http://127.0.0.1:${server.address().port}`, + apiKey: 'test-key', + spaceStateId: 'test-thread', + }), + }); + + await assert.rejects(mcp.listTools()); + assert.deepEqual(clientInfo, { name: 'mantisai-cli', version: packageVersion }); +});