@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,
79 lines (78 loc) • 4.45 kB
JavaScript
import { BaseErrorCode } from "../../../types-global/errors.js"; // Direct import for types-global
import { ErrorHandler, logger, requestContextService, } from "../../../utils/index.js"; // logger (./utils/internal/logger.js), ErrorHandler (./utils/internal/errorHandler.js), requestContextService (./utils/internal/requestContext.js)
// Import the result type along with the function and input schema
import { getGitStatus, GitStatusInputSchema, } from "./logic.js";
let _getWorkingDirectory;
let _getSessionId;
/**
* Initializes the state accessors needed by the tool registration.
* This should be called once during server setup.
* @param getWdFn - Function to get the working directory for a session.
* @param getSidFn - Function to get the session ID from context.
*/
export function initializeGitStatusStateAccessors(getWdFn, getSidFn) {
_getWorkingDirectory = getWdFn;
_getSessionId = getSidFn;
logger.info("State accessors initialized for git_status tool registration.");
}
const TOOL_NAME = "git_status";
const TOOL_DESCRIPTION = "Retrieves the status of a Git repository. Returns a JSON object detailing the current branch, cleanliness, and changes. Staged and unstaged changes are grouped by status (e.g., Added, Modified), alongside lists of untracked and conflicted files.";
/**
* Registers the git_status tool with the MCP server.
* Uses the high-level server.tool() method for registration, schema validation, and routing.
*
* @param {McpServer} server - The McpServer instance to register the tool with.
* @returns {Promise<void>}
* @throws {Error} If registration fails or state accessors are not initialized.
*/
export const registerGitStatusTool = async (server) => {
if (!_getWorkingDirectory || !_getSessionId) {
throw new Error("State accessors for git_status must be initialized before registration.");
}
const operation = "registerGitStatusTool";
const context = requestContextService.createRequestContext({ operation });
await ErrorHandler.tryCatch(async () => {
server.tool(TOOL_NAME, TOOL_DESCRIPTION, GitStatusInputSchema.shape, // Provide the Zod schema shape
async (validatedArgs, callContext) => {
const toolOperation = "tool:git_status";
// Create context, potentially inheriting from callContext
const requestContext = requestContextService.createRequestContext({
operation: toolOperation,
parentContext: callContext,
});
// Get session ID
const sessionId = _getSessionId(requestContext);
// Define the session-specific getter function
const getWorkingDirectoryForSession = () => {
return _getWorkingDirectory(sessionId);
};
// Enhance context for the logic function
const logicContext = {
...requestContext,
sessionId: sessionId,
getWorkingDirectory: getWorkingDirectoryForSession,
};
logger.info(`Executing tool: ${TOOL_NAME}`, logicContext);
// Use ErrorHandler.tryCatch to wrap the logic execution
return await ErrorHandler.tryCatch(async () => {
// Call the core logic function with validated args and enhanced context
const statusResult = await getGitStatus(validatedArgs, logicContext);
// Format the successful result as a JSON string within TextContent
const resultContent = {
type: "text",
// Stringify the JSON object for the response content
text: JSON.stringify(statusResult, null, 2), // Pretty-print JSON
contentType: "application/json", // Specify content type
};
logger.info(`Tool ${TOOL_NAME} executed successfully, returning JSON`, logicContext);
return { content: [resultContent] }; // isError defaults to false
}, {
operation: toolOperation,
context: logicContext,
input: validatedArgs, // Log sanitized input
errorCode: BaseErrorCode.INTERNAL_ERROR, // Default error code if logic fails unexpectedly
});
});
logger.info(`Tool registered: ${TOOL_NAME}`, context);
}, { operation, context, critical: true }); // Treat registration failure as critical
};