#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ErrorCode,
ListToolsRequestSchema,
McpError,
} from '@modelcontextprotocol/sdk/types.js';
import { parseMavenCoordinate } from './maven-client.js';
import * as getLatestStable from './tools/get-latest-stable.js';
import * as getAllVersions from './tools/get-all-versions.js';
import * as checkVersionExists from './tools/check-version-exists.js';
import * as compareVersions from './tools/compare-versions.js';
class MavenVersionServer {
private server: Server;
constructor() {
this.server = new Server(
{
name: 'maven-version-server',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
this.setupToolHandlers();
this.setupErrorHandling();
}
private setupErrorHandling(): void {
this.server.onerror = (error) => {
console.error('[MCP Error]', error);
};
process.on('SIGINT', async () => {
await this.server.close();
process.exit(0);
});
}
private setupToolHandlers(): void {
// List available tools
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
getLatestStable.schema,
getAllVersions.schema,
checkVersionExists.schema,
compareVersions.schema,
],
}));
// Handle tool calls
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
if (name === 'get_latest_stable_version') {
return await this.handleGetLatestStable(args);
}
if (name === 'get_all_versions') {
return await this.handleGetAllVersions(args);
}
if (name === 'check_version_exists') {
return await this.handleCheckVersionExists(args);
}
if (name === 'compare_versions') {
return await this.handleCompareVersions(args);
}
throw new McpError(
ErrorCode.MethodNotFound,
`Unknown tool: ${name}`
);
} catch (error) {
if (error instanceof McpError) {
throw error;
}
const message = error instanceof Error ? error.message : String(error);
throw new McpError(ErrorCode.InternalError, `Error: ${message}`);
}
});
}
private async handleGetLatestStable(args: unknown) {
if (!this.isValidDependencyArgs(args)) {
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: dependency');
}
const coord = parseMavenCoordinate(args.dependency);
return getLatestStable.handler(coord);
}
private async handleGetAllVersions(args: unknown) {
if (!this.isValidDependencyArgs(args)) {
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: dependency');
}
const coord = parseMavenCoordinate(args.dependency);
const stableOnly = (args as any).stableOnly ?? true;
const limit = (args as any).limit ?? 20;
return getAllVersions.handler(coord, stableOnly, limit);
}
private async handleCheckVersionExists(args: unknown) {
if (!this.isValidVersionCheckArgs(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Missing required parameters: dependency, version'
);
}
const coord = parseMavenCoordinate(args.dependency);
return checkVersionExists.handler(coord, args.version);
}
private async handleCompareVersions(args: unknown) {
if (!this.isValidCompareArgs(args)) {
throw new McpError(
ErrorCode.InvalidParams,
'Missing required parameters: dependency, currentVersion'
);
}
const coord = parseMavenCoordinate(args.dependency);
return compareVersions.handler(coord, args.currentVersion, args.targetVersion);
}
private isValidDependencyArgs(args: unknown): args is { dependency: string } {
if (typeof args !== 'object') {
return false;
}
if (args === null) {
return false;
}
return typeof (args as any).dependency === 'string';
}
private isValidVersionCheckArgs(
args: unknown
): args is { dependency: string; version: string } {
if (!this.isValidDependencyArgs(args)) {
return false;
}
return typeof (args as any).version === 'string';
}
private isValidCompareArgs(
args: unknown
): args is { dependency: string; currentVersion: string; targetVersion?: string } {
if (!this.isValidDependencyArgs(args)) {
return false;
}
return typeof (args as any).currentVersion === 'string';
}
async run(): Promise<void> {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error('Maven Version Server running on stdio');
}
}
const server = new MavenVersionServer();
server.run().catch(console.error);