stdio.js•4.88 kB
/**
* Standard I/O utilities for the MCP server
*
* This module provides the base Tool class and a simple stdio-based server
* implementation for the GitHub CLI MCP.
*
* @module stdio
*/
import { McpServer as BaseMcpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
/**
* Tool class for defining GitHub CLI tools
*
* Represents a single tool that can be registered with the MCP server.
* Each tool has a name, schema, handler function, and description.
*
* @class
* @template T The Zod schema type for the tool's parameters
*/
export class Tool {
name;
schema;
handler;
options;
/**
* Creates a new Tool instance
*
* @param {string} name - The name of the tool (e.g., 'gh_pr_list')
* @param {T} schema - Zod schema defining the tool's parameters
* @param {Function} handler - Async function that executes the tool's logic
* @param {Object} options - Additional options for the tool
* @param {string} options.description - Human-readable description of the tool
*/
constructor(name, schema, handler, options) {
this.name = name;
this.schema = schema;
this.handler = handler;
this.options = options;
}
/**
* Returns the tool's definition as a tuple
*
* @returns {Array} A tuple containing [name, schema, handler, options]
*/
definition() {
return [this.name, this.schema, this.handler, this.options];
}
}
/**
* MCP Server for GitHub CLI tools
* @deprecated Use GitHubCliServer from server.ts instead for multi-client support
*/
export class GitHubCliServer extends BaseMcpServer {
toolsList = [];
config;
/**
* Create a new GitHub CLI MCP server
*/
constructor() {
const config = {
name: 'GitHub CLI MCP Server',
version: '1.1.0',
description: 'GitHub CLI commands via Model Context Protocol',
homepage: 'https://github.com/codingbutter/gh-cli-mcp',
license: 'MIT'
};
super(config);
this.config = config;
console.warn('WARNING: This class is deprecated. Use GitHubCliServer from server.ts instead for multi-client support.');
}
/**
* Add a tool with the given name, schema, handler, and options
*/
addTool(name, schema, handler, options) {
const tool = new Tool(name, schema, handler, options);
this.toolsList.push(tool);
// Create a wrapper handler for the MCP SDK
// @ts-ignore - Ignoring type mismatches for now as we're adapting between different versions
const wrappedHandler = async (extra) => {
try {
// Extract sessionId and params from extra if available
const sessionId = extra?.sessionId;
const params = extra?.params || {};
// Call the original handler
const result = await handler(params, sessionId);
// Return in the format expected by the MCP SDK
return {
content: result.content.map(item => {
if (item.type === 'text') {
return { type: 'text', text: item.text };
}
// Handle other types if needed
return item;
}),
_meta: extra?._meta
};
}
catch (error) {
console.error('Handler error:', error);
return {
content: [{ type: 'text', text: 'Error executing command' }],
isError: true
};
}
};
// Register with MCP server
const [toolName, toolSchema, , toolOptions] = tool.definition();
// @ts-ignore - Ignoring type mismatches for compatibility
super.tool(toolName, JSON.stringify(toolOptions), toolSchema?._def?.shape || toolSchema, wrappedHandler);
return this;
}
/**
* Register multiple tools
*/
tools(toolsList) {
for (const tool of toolsList) {
const [name, schema, handler, options] = tool.definition();
this.addTool(name, schema, handler, options);
}
}
/**
* Start the server with stdio transport
*/
async start() {
const transport = new StdioServerTransport();
await this.connect(transport);
console.error('🚀 GitHub CLI MCP Server running on stdio');
// Return a close function that uses the transport's close method
return {
close: () => {
transport.close();
console.error('MCP server closed');
}
};
}
}
//# sourceMappingURL=stdio.js.map