UNPKG

@cyanheads/git-mcp-server

Version:

An MCP (Model Context Protocol) server enabling LLMs and AI agents to interact with Git repositories. Provides tools for comprehensive Git operations including clone, commit, branch, diff, log, status, push, pull, merge, rebase, worktree, tag management,

84 lines (83 loc) 4.41 kB
// Import utils from barrel (logger from ../utils/internal/logger.js) import { logger } from "../../../utils/index.js"; // Import utils from barrel (ErrorHandler from ../utils/internal/errorHandler.js) import { ErrorHandler } from "../../../utils/index.js"; // Import utils from barrel (requestContextService from ../utils/internal/requestContext.js) import { BaseErrorCode } from "../../../types-global/errors.js"; // Keep direct import for types-global import { requestContextService } from "../../../utils/index.js"; import { GitMergeInputSchema, gitMergeLogic, } from "./logic.js"; let _getWorkingDirectory; let _getSessionId; /** * Initializes the state accessors needed by the gitMerge tool registration. * @param getWdFn - Function to get the working directory for a session. * @param getSidFn - Function to get the session ID from context. */ export function initializeGitMergeStateAccessors(getWdFn, getSidFn) { _getWorkingDirectory = getWdFn; _getSessionId = getSidFn; logger.info("State accessors initialized for git_merge tool registration."); } const TOOL_NAME = "git_merge"; const TOOL_DESCRIPTION = "Merges the specified branch into the current branch. Supports options like --no-ff, --squash, and --abort. Returns the merge result as a JSON object."; /** * Registers the git_merge tool with the MCP server. * * @param {McpServer} server - The McpServer instance. * @returns {Promise<void>} * @throws {Error} If registration fails or state accessors are not initialized. */ export const registerGitMergeTool = async (server) => { if (!_getWorkingDirectory || !_getSessionId) { throw new Error("State accessors for git_merge must be initialized before registration."); } const operation = "registerGitMergeTool"; const context = requestContextService.createRequestContext({ operation }); await ErrorHandler.tryCatch(async () => { server.tool(TOOL_NAME, TOOL_DESCRIPTION, GitMergeInputSchema.shape, // Provide the Zod schema shape async (validatedArgs, callContext) => { const toolOperation = "tool:git_merge"; const requestContext = requestContextService.createRequestContext({ operation: toolOperation, parentContext: callContext, }); const sessionId = _getSessionId(requestContext); const getWorkingDirectoryForSession = () => { return _getWorkingDirectory(sessionId); }; const logicContext = { ...requestContext, sessionId: sessionId, getWorkingDirectory: getWorkingDirectoryForSession, }; logger.info(`Executing tool: ${TOOL_NAME}`, logicContext); return await ErrorHandler.tryCatch(async () => { // Call the core logic function const mergeResult = await gitMergeLogic(validatedArgs, logicContext); // Format the result as a JSON string within TextContent const resultContent = { type: "text", text: JSON.stringify(mergeResult, null, 2), // Pretty-print JSON contentType: "application/json", }; // Log based on the success flag in the result if (mergeResult.success) { logger.info(`Tool ${TOOL_NAME} executed successfully, returning JSON`, logicContext); } else { // Log non-fatal conditions (like conflicts) differently from execution errors logger.info(`Tool ${TOOL_NAME} completed with specific condition (e.g., conflict, no merge to abort), returning JSON`, logicContext); } // Even if success is false (e.g., conflicts), it's not a tool execution *error* in the MCP sense, // the tool ran, but the git operation failed predictably. Return the structured result. return { content: [resultContent] }; }, { operation: toolOperation, context: logicContext, input: validatedArgs, errorCode: BaseErrorCode.INTERNAL_ERROR, // Default for unexpected logic errors }); }); logger.info(`Tool registered: ${TOOL_NAME}`, context); }, { operation, context, critical: true }); };