Skip to content

Commit dc0cbaf

Browse files
meorphismeorphis
andauthored
add mcp server version updates (#202)
* add mcp server version updates * lint --------- Co-authored-by: meorphis <[email protected]>
1 parent 089239f commit dc0cbaf

File tree

6 files changed

+227
-0
lines changed

6 files changed

+227
-0
lines changed

__snapshots__/mcp-server.ts.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
exports['McpServer updateContent updates the version 1'] = `
2+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
3+
4+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
5+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
6+
import { tools, handlers, HandlerFunction } from './tools';
7+
import { CallToolRequestSchema, ListToolsRequestSchema, Tool } from '@modelcontextprotocol/sdk/types.js';
8+
import ModernTreasury from 'modern-treasury';
9+
export { tools, handlers } from './tools';
10+
11+
// Create server instance
12+
export const server = new McpServer(
13+
{
14+
name: 'modern_treasury_api',
15+
version: '2.36.1',
16+
},
17+
{
18+
capabilities: {
19+
tools: {},
20+
},
21+
},
22+
);
23+
24+
/**
25+
* Initializes the provided MCP Server with the given tools and handlers.
26+
* If not provided, the default client, tools and handlers will be used.
27+
*/
28+
export function init(params: {
29+
server: Server | McpServer;
30+
client?: ModernTreasury;
31+
tools?: Tool[];
32+
handlers?: Record<string, HandlerFunction>;
33+
}) {
34+
const server = params.server instanceof McpServer ? params.server.server : params.server;
35+
const providedTools = params.tools || tools;
36+
const providedHandlers = params.handlers || handlers;
37+
const client = params.client || new ModernTreasury({});
38+
39+
server.setRequestHandler(ListToolsRequestSchema, async () => {
40+
return {
41+
tools: providedTools,
42+
};
43+
});
44+
45+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
46+
const { name, arguments: args } = request.params;
47+
48+
const handler = providedHandlers[name];
49+
if (!handler) {
50+
throw new Error(\`Unknown tool: \${name}\`);
51+
}
52+
53+
return executeHandler(handler, client, args);
54+
});
55+
}
56+
57+
/**
58+
* Runs the provided handler with the given client and arguments.
59+
*/
60+
export async function executeHandler(
61+
handler: HandlerFunction,
62+
client: ModernTreasury,
63+
args: Record<string, unknown> | undefined,
64+
) {
65+
const result = await handler(client, args || {});
66+
return {
67+
content: [
68+
{
69+
type: 'text',
70+
text: JSON.stringify(result, null, 2),
71+
},
72+
],
73+
};
74+
}
75+
76+
export const readEnv = (env: string): string => {
77+
let envValue = undefined;
78+
if (typeof (globalThis as any).process !== 'undefined') {
79+
envValue = (globalThis as any).process.env?.[env]?.trim();
80+
} else if (typeof (globalThis as any).Deno !== 'undefined') {
81+
envValue = (globalThis as any).Deno.env?.get?.(env)?.trim();
82+
}
83+
if (envValue === undefined) {
84+
throw new Error(\`Environment variable \${env} is not set\`);
85+
}
86+
return envValue;
87+
};
88+
`

src/strategies/node.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {PackageJson} from '../updaters/node/package-json';
2222
import {GitHubFileContents} from '@google-automations/git-file-utils';
2323
import {FileNotFoundError, MissingRequiredFileError} from '../errors';
2424
import {filterCommits} from '../util/filter-commits';
25+
import {McpServer} from '../updaters/node/mcp-server';
2526

2627
export class Node extends BaseStrategy {
2728
private pkgJsonContents?: GitHubFileContents;
@@ -70,6 +71,14 @@ export class Node extends BaseStrategy {
7071
}),
7172
});
7273

74+
updates.push({
75+
path: this.addPath('packages/mcp-server/src/server.ts'),
76+
createIfMissing: false,
77+
updater: new McpServer({
78+
version,
79+
}),
80+
});
81+
7382
// If a machine readable changelog.json exists update it:
7483
if (options.commits && packageName) {
7584
const commits = filterCommits(options.commits, this.changelogSections);

src/updaters/node/mcp-server.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {DefaultUpdater} from '../default';
2+
import {logger as defaultLogger, Logger} from '../../util/logger';
3+
4+
/**
5+
* This updates an MCP server's version
6+
*/
7+
export class McpServer extends DefaultUpdater {
8+
/**
9+
* Given initial file contents, return updated contents.
10+
* @param {string} content The initial content
11+
* @returns {string} The updated content
12+
*/
13+
updateContent(content: string, logger: Logger = defaultLogger): string {
14+
logger.info(`updating to ${this.version}`);
15+
return content.replace(/version: '.*'/, `version: '${this.version}'`);
16+
}
17+
}

test/strategies/node.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {ChangelogJson} from '../../src/updaters/changelog-json';
3333
import * as assert from 'assert';
3434
import {MissingRequiredFileError, FileNotFoundError} from '../../src/errors';
3535
import snapshot = require('snap-shot-it');
36+
import {McpServer} from '../../src/updaters/node/mcp-server';
3637

3738
nock.disableNetConnect();
3839
const sandbox = sinon.createSandbox();
@@ -244,6 +245,7 @@ describe('Node', () => {
244245
const updater = update.updater as SamplesPackageJson;
245246
expect(updater.packageName).to.equal('google-cloud-automl-pkg');
246247
assertHasUpdate(updates, 'package.json', PackageJson);
248+
assertHasUpdate(updates, 'packages/mcp-server/src/server.ts', McpServer);
247249
});
248250
});
249251
});
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
4+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5+
import { tools, handlers, HandlerFunction } from './tools';
6+
import { CallToolRequestSchema, ListToolsRequestSchema, Tool } from '@modelcontextprotocol/sdk/types.js';
7+
import ModernTreasury from 'modern-treasury';
8+
export { tools, handlers } from './tools';
9+
10+
// Create server instance
11+
export const server = new McpServer(
12+
{
13+
name: 'modern_treasury_api',
14+
version: '2.36.0',
15+
},
16+
{
17+
capabilities: {
18+
tools: {},
19+
},
20+
},
21+
);
22+
23+
/**
24+
* Initializes the provided MCP Server with the given tools and handlers.
25+
* If not provided, the default client, tools and handlers will be used.
26+
*/
27+
export function init(params: {
28+
server: Server | McpServer;
29+
client?: ModernTreasury;
30+
tools?: Tool[];
31+
handlers?: Record<string, HandlerFunction>;
32+
}) {
33+
const server = params.server instanceof McpServer ? params.server.server : params.server;
34+
const providedTools = params.tools || tools;
35+
const providedHandlers = params.handlers || handlers;
36+
const client = params.client || new ModernTreasury({});
37+
38+
server.setRequestHandler(ListToolsRequestSchema, async () => {
39+
return {
40+
tools: providedTools,
41+
};
42+
});
43+
44+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
45+
const { name, arguments: args } = request.params;
46+
47+
const handler = providedHandlers[name];
48+
if (!handler) {
49+
throw new Error(`Unknown tool: ${name}`);
50+
}
51+
52+
return executeHandler(handler, client, args);
53+
});
54+
}
55+
56+
/**
57+
* Runs the provided handler with the given client and arguments.
58+
*/
59+
export async function executeHandler(
60+
handler: HandlerFunction,
61+
client: ModernTreasury,
62+
args: Record<string, unknown> | undefined,
63+
) {
64+
const result = await handler(client, args || {});
65+
return {
66+
content: [
67+
{
68+
type: 'text',
69+
text: JSON.stringify(result, null, 2),
70+
},
71+
],
72+
};
73+
}
74+
75+
export const readEnv = (env: string): string => {
76+
let envValue = undefined;
77+
if (typeof (globalThis as any).process !== 'undefined') {
78+
envValue = (globalThis as any).process.env?.[env]?.trim();
79+
} else if (typeof (globalThis as any).Deno !== 'undefined') {
80+
envValue = (globalThis as any).Deno.env?.get?.(env)?.trim();
81+
}
82+
if (envValue === undefined) {
83+
throw new Error(`Environment variable ${env} is not set`);
84+
}
85+
return envValue;
86+
};

test/updaters/mcp-server.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {readFileSync} from 'fs';
2+
import {resolve} from 'path';
3+
import snapshot = require('snap-shot-it');
4+
import {describe, it} from 'mocha';
5+
import {Version} from '../../src/version';
6+
import {McpServer} from '../../src/updaters/node/mcp-server';
7+
8+
const fixturesPath = './test/updaters/fixtures';
9+
10+
describe('McpServer', () => {
11+
describe('updateContent', () => {
12+
it('updates the version', async () => {
13+
const oldContent = readFileSync(
14+
// it's a .txt file rather than .ts so that the linter doesn't complain
15+
resolve(fixturesPath, './mcp_server.txt'),
16+
'utf8'
17+
);
18+
const packageJson = new McpServer({
19+
version: Version.parse('2.36.1'),
20+
});
21+
const newContent = packageJson.updateContent(oldContent);
22+
snapshot(newContent.replace(/\r\n/g, '\n'));
23+
});
24+
});
25+
});

0 commit comments

Comments
 (0)