#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
Tool,
} from '@modelcontextprotocol/sdk/types.js';
import { DevOpsApiClient } from './api/index.js';
import { DockerTools, GitLabTools } from './tools/index.js';
/**
* DevOps MCP Server
* Provides tools for Docker image management and GitLab CI operations
*/
class DevOpsMcpServer {
private server: Server;
private apiClient: DevOpsApiClient;
private dockerTools: DockerTools;
private gitlabTools: GitLabTools;
constructor() {
// Initialize API client
this.apiClient = new DevOpsApiClient();
// Initialize tools
this.dockerTools = new DockerTools(this.apiClient);
this.gitlabTools = new GitLabTools(this.apiClient);
// Initialize MCP server
this.server = new Server(
{
name: 'devops-mcp-server',
version: '0.1.0',
},
{
capabilities: {
tools: {},
},
}
);
this.setupHandlers();
}
/**
* Setup MCP request handlers
*/
private setupHandlers(): void {
// List available tools
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: this.getToolDefinitions(),
};
});
// Handle tool calls
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
// Docker tools
case 'search_docker_images':
return {
content: [
{
type: 'text',
text: await this.dockerTools.searchImages(String(args?.keyword || '')),
},
],
};
case 'get_docker_image_tags':
return {
content: [
{
type: 'text',
text: await this.dockerTools.getImageTags(String(args?.imageName || '')),
},
],
};
// GitLab CI tools
case 'search_gitlab_references':
return {
content: [
{
type: 'text',
text: await this.gitlabTools.searchReferences(String(args?.keyword || '')),
},
],
};
case 'get_gitlab_reference_versions':
return {
content: [
{
type: 'text',
text: await this.gitlabTools.getReferenceVersions(String(args?.referenceName || '')),
},
],
};
case 'get_gitlab_pipeline_info':
return {
content: [
{
type: 'text',
text: await this.gitlabTools.getPipelineInfo(String(args?.pipelineName || '')),
},
],
};
default:
throw new Error(`Unknown tool: ${name}`);
}
} catch (error) {
return {
content: [
{
type: 'text',
text: `Error executing tool "${name}": ${error instanceof Error ? error.message : String(error)}`,
},
],
isError: true,
};
}
});
}
/**
* Get tool definitions for MCP
*/
private getToolDefinitions(): Tool[] {
return [
// Docker tools
{
name: 'search_docker_images',
description: 'Search for Docker images by keyword. Returns a list of available Docker images matching the search term.',
inputSchema: {
type: 'object',
properties: {
keyword: {
type: 'string',
description: 'Keyword to search for Docker images (e.g., "nginx", "postgres", "node")',
},
},
required: ['keyword'],
},
},
{
name: 'get_docker_image_tags',
description: 'Get all available tags for a specific Docker image. Returns version tags, sizes, and update dates.',
inputSchema: {
type: 'object',
properties: {
imageName: {
type: 'string',
description: 'Name of the Docker image (e.g., "nginx", "postgres:14")',
},
},
required: ['imageName'],
},
},
// GitLab CI tools
{
name: 'search_gitlab_references',
description: 'Search for GitLab CI reference YAML files by keyword. Returns available CI/CD templates and configurations.',
inputSchema: {
type: 'object',
properties: {
keyword: {
type: 'string',
description: 'Keyword to search for GitLab CI references (e.g., "node", "python", "docker")',
},
},
required: ['keyword'],
},
},
{
name: 'get_gitlab_reference_versions',
description: 'Get all available versions for a specific GitLab CI reference. Returns version history and changelog.',
inputSchema: {
type: 'object',
properties: {
referenceName: {
type: 'string',
description: 'Name of the GitLab CI reference',
},
},
required: ['referenceName'],
},
},
{
name: 'get_gitlab_pipeline_info',
description: 'Get detailed information about a GitLab CI custom pipeline. Returns stages, variables, and template configuration.',
inputSchema: {
type: 'object',
properties: {
pipelineName: {
type: 'string',
description: 'Name of the GitLab CI pipeline',
},
},
required: ['pipelineName'],
},
},
];
}
/**
* Start the MCP server
*/
async start(): Promise<void> {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error('DevOps MCP Server running on stdio');
}
}
// Start the server
const server = new DevOpsMcpServer();
server.start().catch((error) => {
console.error('Failed to start server:', error);
process.exit(1);
});