@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,
77 lines (76 loc) • 3.93 kB
JavaScript
// Import utils from barrel (ErrorHandler from ../utils/internal/errorHandler.js)
import { ErrorHandler } from "../../../utils/index.js";
// Import utils from barrel (logger from ../utils/internal/logger.js)
import { logger } from "../../../utils/index.js";
// Import utils from barrel (requestContextService, RequestContext 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 { fetchGitRemote, GitFetchInputSchema, } 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 initializeGitFetchStateAccessors(getWdFn, getSidFn) {
_getWorkingDirectory = getWdFn;
_getSessionId = getSidFn;
logger.info("State accessors initialized for git_fetch tool registration.");
}
const TOOL_NAME = "git_fetch";
const TOOL_DESCRIPTION = "Downloads objects and refs from one or more other repositories. Can fetch specific remotes or all, prune stale branches, and fetch tags.";
/**
* Registers the git_fetch tool with the MCP server.
*
* @param {McpServer} server - The MCP server instance.
* @throws {Error} If state accessors are not initialized.
*/
export async function registerGitFetchTool(server) {
if (!_getWorkingDirectory || !_getSessionId) {
throw new Error("State accessors for git_fetch must be initialized before registration.");
}
const operation = "registerGitFetchTool";
const context = requestContextService.createRequestContext({ operation });
await ErrorHandler.tryCatch(async () => {
server.tool(TOOL_NAME, TOOL_DESCRIPTION, GitFetchInputSchema.shape, // Provide the Zod schema shape
async (validatedArgs, callContext) => {
const toolOperation = "tool:git_fetch";
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 fetchResult = await fetchGitRemote(validatedArgs, logicContext);
// Format the result as a JSON string within TextContent
const resultContent = {
type: "text",
// Stringify the entire GitFetchResult object
text: JSON.stringify(fetchResult, null, 2), // Pretty-print JSON
contentType: "application/json",
};
logger.info(`Tool ${TOOL_NAME} executed successfully: ${fetchResult.message}`, logicContext);
// Success is determined by the logic function and included in the result object
return { content: [resultContent] };
}, {
operation: toolOperation,
context: logicContext,
input: validatedArgs,
errorCode: BaseErrorCode.INTERNAL_ERROR, // Default if unexpected error in logic
});
});
logger.info(`Tool registered: ${TOOL_NAME}`, context);
}, { operation, context, critical: true });
}