@cyanheads/git-mcp-server 2.1.8 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/mcp-server/server.js +69 -228
- package/dist/mcp-server/tools/gitAdd/index.js +2 -4
- package/dist/mcp-server/tools/gitAdd/logic.js +17 -74
- package/dist/mcp-server/tools/gitAdd/registration.js +38 -59
- package/dist/mcp-server/tools/gitBranch/index.js +3 -5
- package/dist/mcp-server/tools/gitBranch/logic.js +118 -296
- package/dist/mcp-server/tools/gitBranch/registration.js +52 -66
- package/dist/mcp-server/tools/gitCheckout/index.js +2 -3
- package/dist/mcp-server/tools/gitCheckout/logic.js +47 -122
- package/dist/mcp-server/tools/gitCheckout/registration.js +53 -72
- package/dist/mcp-server/tools/gitCherryPick/index.js +3 -5
- package/dist/mcp-server/tools/gitCherryPick/logic.js +55 -162
- package/dist/mcp-server/tools/gitCherryPick/registration.js +52 -67
- package/dist/mcp-server/tools/gitClean/index.js +3 -5
- package/dist/mcp-server/tools/gitClean/logic.js +44 -143
- package/dist/mcp-server/tools/gitClean/registration.js +52 -92
- package/dist/mcp-server/tools/gitClearWorkingDir/index.js +3 -5
- package/dist/mcp-server/tools/gitClearWorkingDir/logic.js +19 -26
- package/dist/mcp-server/tools/gitClearWorkingDir/registration.js +55 -73
- package/dist/mcp-server/tools/gitClone/index.js +2 -4
- package/dist/mcp-server/tools/gitClone/logic.js +50 -171
- package/dist/mcp-server/tools/gitClone/registration.js +51 -42
- package/dist/mcp-server/tools/gitCommit/index.js +2 -4
- package/dist/mcp-server/tools/gitCommit/logic.js +90 -295
- package/dist/mcp-server/tools/gitCommit/registration.js +52 -73
- package/dist/mcp-server/tools/gitDiff/index.js +2 -3
- package/dist/mcp-server/tools/gitDiff/logic.js +78 -254
- package/dist/mcp-server/tools/gitDiff/registration.js +53 -68
- package/dist/mcp-server/tools/gitFetch/index.js +2 -3
- package/dist/mcp-server/tools/gitFetch/logic.js +47 -129
- package/dist/mcp-server/tools/gitFetch/registration.js +54 -66
- package/dist/mcp-server/tools/gitInit/index.js +3 -5
- package/dist/mcp-server/tools/gitInit/logic.js +46 -152
- package/dist/mcp-server/tools/gitInit/registration.js +52 -104
- package/dist/mcp-server/tools/gitLog/index.js +2 -3
- package/dist/mcp-server/tools/gitLog/logic.js +75 -257
- package/dist/mcp-server/tools/gitLog/registration.js +54 -66
- package/dist/mcp-server/tools/gitMerge/index.js +3 -5
- package/dist/mcp-server/tools/gitMerge/logic.js +52 -179
- package/dist/mcp-server/tools/gitMerge/registration.js +52 -71
- package/dist/mcp-server/tools/gitPull/index.js +2 -3
- package/dist/mcp-server/tools/gitPull/logic.js +48 -146
- package/dist/mcp-server/tools/gitPull/registration.js +53 -75
- package/dist/mcp-server/tools/gitPush/index.js +2 -3
- package/dist/mcp-server/tools/gitPush/logic.js +73 -181
- package/dist/mcp-server/tools/gitPush/registration.js +53 -75
- package/dist/mcp-server/tools/gitRebase/index.js +3 -5
- package/dist/mcp-server/tools/gitRebase/logic.js +73 -202
- package/dist/mcp-server/tools/gitRebase/registration.js +52 -70
- package/dist/mcp-server/tools/gitRemote/index.js +3 -5
- package/dist/mcp-server/tools/gitRemote/logic.js +85 -193
- package/dist/mcp-server/tools/gitRemote/registration.js +52 -65
- package/dist/mcp-server/tools/gitReset/index.js +2 -3
- package/dist/mcp-server/tools/gitReset/logic.js +37 -121
- package/dist/mcp-server/tools/gitReset/registration.js +53 -60
- package/dist/mcp-server/tools/gitSetWorkingDir/index.js +3 -5
- package/dist/mcp-server/tools/gitSetWorkingDir/logic.js +45 -133
- package/dist/mcp-server/tools/gitSetWorkingDir/registration.js +55 -85
- package/dist/mcp-server/tools/gitShow/index.js +3 -5
- package/dist/mcp-server/tools/gitShow/logic.js +33 -122
- package/dist/mcp-server/tools/gitShow/registration.js +52 -74
- package/dist/mcp-server/tools/gitStash/index.js +3 -5
- package/dist/mcp-server/tools/gitStash/logic.js +70 -214
- package/dist/mcp-server/tools/gitStash/registration.js +52 -77
- package/dist/mcp-server/tools/gitStatus/index.js +2 -4
- package/dist/mcp-server/tools/gitStatus/logic.js +82 -229
- package/dist/mcp-server/tools/gitStatus/registration.js +52 -66
- package/dist/mcp-server/tools/gitTag/index.js +3 -5
- package/dist/mcp-server/tools/gitTag/logic.js +66 -188
- package/dist/mcp-server/tools/gitTag/registration.js +54 -73
- package/dist/mcp-server/tools/gitWorktree/index.js +3 -5
- package/dist/mcp-server/tools/gitWorktree/logic.js +112 -322
- package/dist/mcp-server/tools/gitWorktree/registration.js +54 -58
- package/dist/mcp-server/tools/gitWrapupInstructions/index.js +5 -3
- package/dist/mcp-server/tools/gitWrapupInstructions/logic.js +26 -38
- package/dist/mcp-server/tools/gitWrapupInstructions/registration.js +54 -70
- package/dist/mcp-server/transports/httpTransport.js +2 -3
- package/package.json +8 -8
|
@@ -1,18 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Defines the core logic, schemas, and types for the git_wrapup_instructions tool.
|
|
3
|
+
* @module src/mcp-server/tools/gitWrapupInstructions/logic
|
|
4
|
+
*/
|
|
1
5
|
import { z } from "zod";
|
|
2
|
-
import { logger } from "../../../utils/index.js";
|
|
3
|
-
import { getGitStatus } from "../gitStatus/logic.js";
|
|
4
|
-
//
|
|
6
|
+
import { logger } from "../../../utils/index.js";
|
|
7
|
+
import { getGitStatus, GitStatusOutputSchema } from "../gitStatus/logic.js";
|
|
8
|
+
// 1. DEFINE the Zod input schema.
|
|
5
9
|
export const GitWrapupInstructionsInputSchema = z.object({
|
|
6
|
-
acknowledgement: z.enum(["Y", "y", "Yes", "yes"],
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
acknowledgement: z.enum(["Y", "y", "Yes", "yes"]).describe("Acknowledgement to initiate the wrap-up workflow."),
|
|
11
|
+
updateAgentMetaFiles: z.enum(["Y", "y", "Yes", "yes"]).optional().describe("Include an instruction to update agent-specific meta files."),
|
|
12
|
+
});
|
|
13
|
+
// 2. DEFINE the Zod response schema.
|
|
14
|
+
export const GitWrapupInstructionsOutputSchema = z.object({
|
|
15
|
+
instructions: z.string().describe("The set of instructions for the wrap-up workflow."),
|
|
16
|
+
gitStatus: GitStatusOutputSchema.optional().describe("The current structured git status."),
|
|
17
|
+
gitStatusError: z.string().optional().describe("Any error message if getting git status failed."),
|
|
14
18
|
});
|
|
15
|
-
// The predefined instructions string.
|
|
16
19
|
const WRAPUP_INSTRUCTIONS = `
|
|
17
20
|
Perform all actions for our git wrapup workflow:
|
|
18
21
|
1. Use the git_diff tool to understand the precise nature and rationale behind each change (what changed and why did it change?) within the code base. Use the 'includeUntracked' parameter to view all changes, including untracked files. This will help you understand the context and purpose of the modifications made.
|
|
@@ -24,46 +27,31 @@ Note: Be sure to set 'git_set_working_dir' if not already set.
|
|
|
24
27
|
Instructions: Now write a concise list of what you must do to complete the git wrapup workflow, then perform all actions. Do not push unless requested.
|
|
25
28
|
`;
|
|
26
29
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* @param {GitWrapupInstructionsInput} input - The validated input, may contain 'updateAgentMetaFiles'.
|
|
31
|
-
* @param {RequestContext} _context - The request context (included for consistency, not used in this simple logic).
|
|
32
|
-
* @returns {Promise<GitWrapupInstructionsResult>} A promise that resolves with the wrap-up instructions.
|
|
30
|
+
* 4. IMPLEMENT the core logic function.
|
|
31
|
+
* @throws {McpError} If the logic encounters an unrecoverable issue.
|
|
33
32
|
*/
|
|
34
|
-
export async function getWrapupInstructions(
|
|
35
|
-
// The context is now expected to be enhanced by the registration layer
|
|
36
|
-
// to include session-specific methods like getWorkingDirectory.
|
|
37
|
-
context) {
|
|
33
|
+
export async function getWrapupInstructions(params, context) {
|
|
38
34
|
const operation = "getWrapupInstructions";
|
|
39
|
-
logger.debug(`Executing ${operation}`, { ...context,
|
|
35
|
+
logger.debug(`Executing ${operation}`, { ...context, params });
|
|
40
36
|
let finalInstructions = WRAPUP_INSTRUCTIONS;
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
finalInstructions += ` Extra request: review and update if needed the .clinerules and claude.md files if present.`;
|
|
37
|
+
if (params.updateAgentMetaFiles) {
|
|
38
|
+
finalInstructions += `\nExtra request: review and update if needed the .clinerules and claude.md files if present.`;
|
|
44
39
|
}
|
|
45
|
-
let statusResult
|
|
46
|
-
let statusError
|
|
40
|
+
let statusResult;
|
|
41
|
+
let statusError;
|
|
47
42
|
const workingDir = context.getWorkingDirectory();
|
|
48
43
|
if (workingDir) {
|
|
49
44
|
try {
|
|
50
|
-
// The `getGitStatus` function expects `path` and a context with `getWorkingDirectory`.
|
|
51
|
-
// Passing `path: '.'` signals `getGitStatus` to use the working directory from the context.
|
|
52
|
-
// The `registration.ts` for this tool will be responsible for ensuring `context.getWorkingDirectory` is correctly supplied.
|
|
53
45
|
statusResult = await getGitStatus({ path: "." }, context);
|
|
54
46
|
}
|
|
55
47
|
catch (error) {
|
|
56
|
-
logger.warning(`Failed to get git status
|
|
57
|
-
|
|
58
|
-
tool: "gitWrapupInstructions",
|
|
59
|
-
originalError: error.message,
|
|
60
|
-
});
|
|
61
|
-
statusError = error instanceof Error ? error.message : String(error);
|
|
48
|
+
logger.warning(`Failed to get git status for wrapup instructions: ${error.message}`, { ...context, operation });
|
|
49
|
+
statusError = error.message;
|
|
62
50
|
}
|
|
63
51
|
}
|
|
64
52
|
else {
|
|
65
|
-
logger.info("No working directory set for session, skipping git status for wrapup instructions.", { ...context, tool: "gitWrapupInstructions" });
|
|
66
53
|
statusError = "No working directory set for session, git status skipped.";
|
|
54
|
+
logger.info(statusError, { ...context, operation });
|
|
67
55
|
}
|
|
68
56
|
return {
|
|
69
57
|
instructions: finalInstructions,
|
|
@@ -1,80 +1,64 @@
|
|
|
1
|
-
import { BaseErrorCode } from "../../../types-global/errors.js";
|
|
2
|
-
import { ErrorHandler, logger, requestContextService, } from "../../../utils/index.js";
|
|
3
|
-
import { getWrapupInstructions, GitWrapupInstructionsInputSchema, } from "./logic.js";
|
|
4
|
-
let _getWorkingDirectory;
|
|
5
|
-
let _getSessionId;
|
|
6
1
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* @param getWdFn - Function to get the working directory for a session.
|
|
10
|
-
* @param getSidFn - Function to get the session ID from context.
|
|
2
|
+
* @fileoverview Handles registration and error handling for the git_wrapup_instructions tool.
|
|
3
|
+
* @module src/mcp-server/tools/gitWrapupInstructions/registration
|
|
11
4
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
logger.info("State accessors initialized for git_wrapup_instructions tool registration.");
|
|
16
|
-
}
|
|
5
|
+
import { ErrorHandler, logger, requestContextService } from "../../../utils/index.js";
|
|
6
|
+
import { McpError, BaseErrorCode } from "../../../types-global/errors.js";
|
|
7
|
+
import { getWrapupInstructions, GitWrapupInstructionsInputSchema, GitWrapupInstructionsOutputSchema, } from "./logic.js";
|
|
17
8
|
const TOOL_NAME = "git_wrapup_instructions";
|
|
18
9
|
const TOOL_DESCRIPTION = "Provides a standard Git wrap-up workflow. This involves reviewing changes with `git_diff`, updating documentation (README, CHANGELOG), and making logical, descriptive commits using the `git_commit` tool. The tool's response also includes the current `git status` output. You should set the working directory using `git_set_working_dir` before running this tool.";
|
|
19
10
|
/**
|
|
20
|
-
* Registers the git_wrapup_instructions tool with the MCP server.
|
|
21
|
-
*
|
|
22
|
-
* @param
|
|
23
|
-
* @
|
|
24
|
-
* @throws {Error} If registration fails or state accessors are not initialized.
|
|
11
|
+
* Registers the git_wrapup_instructions tool with the MCP server instance.
|
|
12
|
+
* @param server The MCP server instance.
|
|
13
|
+
* @param getWorkingDirectory Function to get the session's working directory.
|
|
14
|
+
* @param getSessionId Function to get the session ID from context.
|
|
25
15
|
*/
|
|
26
|
-
export const registerGitWrapupInstructionsTool = async (server) => {
|
|
27
|
-
if (!_getWorkingDirectory || !_getSessionId) {
|
|
28
|
-
throw new Error("State accessors for git_wrapup_instructions must be initialized before registration.");
|
|
29
|
-
}
|
|
16
|
+
export const registerGitWrapupInstructionsTool = async (server, getWorkingDirectory, getSessionId) => {
|
|
30
17
|
const operation = "registerGitWrapupInstructionsTool";
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
sessionId: sessionId,
|
|
58
|
-
getWorkingDirectory: getWorkingDirectoryForSession,
|
|
18
|
+
const context = requestContextService.createRequestContext({ operation });
|
|
19
|
+
server.registerTool(TOOL_NAME, {
|
|
20
|
+
title: "Git Wrap-up Instructions",
|
|
21
|
+
description: TOOL_DESCRIPTION,
|
|
22
|
+
inputSchema: GitWrapupInstructionsInputSchema.shape,
|
|
23
|
+
outputSchema: GitWrapupInstructionsOutputSchema.shape,
|
|
24
|
+
annotations: {
|
|
25
|
+
readOnlyHint: true,
|
|
26
|
+
destructiveHint: false,
|
|
27
|
+
idempotentHint: true,
|
|
28
|
+
openWorldHint: false,
|
|
29
|
+
},
|
|
30
|
+
}, async (params, callContext) => {
|
|
31
|
+
const handlerContext = requestContextService.createRequestContext({
|
|
32
|
+
toolName: TOOL_NAME,
|
|
33
|
+
parentContext: callContext,
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
const sessionId = getSessionId(handlerContext);
|
|
37
|
+
const result = await getWrapupInstructions(params, {
|
|
38
|
+
...handlerContext,
|
|
39
|
+
getWorkingDirectory: () => getWorkingDirectory(sessionId),
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
structuredContent: result,
|
|
43
|
+
content: [{ type: "text", text: `Success: ${JSON.stringify(result, null, 2)}` }],
|
|
59
44
|
};
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
contentType: "application/json",
|
|
68
|
-
};
|
|
69
|
-
logger.info(`Tool ${TOOL_NAME} executed successfully, returning JSON`, logicContext);
|
|
70
|
-
return { content: [resultContent] };
|
|
71
|
-
}, {
|
|
72
|
-
operation: toolOperation,
|
|
73
|
-
context: logicContext, // Use the enhanced logicContext for error reporting
|
|
74
|
-
input: validatedArgs,
|
|
75
|
-
errorCode: BaseErrorCode.INTERNAL_ERROR,
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
logger.error(`Error in ${TOOL_NAME} handler`, { error, ...handlerContext });
|
|
48
|
+
const handledError = ErrorHandler.handleError(error, {
|
|
49
|
+
operation: `tool:${TOOL_NAME}`,
|
|
50
|
+
context: handlerContext,
|
|
51
|
+
input: params,
|
|
76
52
|
});
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
53
|
+
const mcpError = handledError instanceof McpError
|
|
54
|
+
? handledError
|
|
55
|
+
: new McpError(BaseErrorCode.INTERNAL_ERROR, "An unexpected error occurred.", { originalError: handledError });
|
|
56
|
+
return {
|
|
57
|
+
isError: true,
|
|
58
|
+
content: [{ type: "text", text: mcpError.message }],
|
|
59
|
+
structuredContent: mcpError.details,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
logger.info(`Tool '${TOOL_NAME}' registered successfully.`, context);
|
|
80
64
|
};
|
|
@@ -97,7 +97,7 @@ function startHttpServerWithRetry(app, initialPort, host, maxRetries, parentCont
|
|
|
97
97
|
reject(new Error("Failed to bind to any port after multiple retries."));
|
|
98
98
|
});
|
|
99
99
|
}
|
|
100
|
-
export async function startHttpTransport(
|
|
100
|
+
export async function startHttpTransport(server, parentContext) {
|
|
101
101
|
const app = new Hono();
|
|
102
102
|
const transportContext = requestContextService.createRequestContext({
|
|
103
103
|
...parentContext,
|
|
@@ -180,8 +180,7 @@ export async function startHttpTransport(createServerInstanceFn, parentContext)
|
|
|
180
180
|
});
|
|
181
181
|
}
|
|
182
182
|
};
|
|
183
|
-
// Connect the new transport to
|
|
184
|
-
const server = await createServerInstanceFn();
|
|
183
|
+
// Connect the new transport to the existing server instance.
|
|
185
184
|
await server.connect(newTransport);
|
|
186
185
|
transport = newTransport;
|
|
187
186
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/git-mcp-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "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, and more, via the MCP standard. STDIO & HTTP.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"files": [
|
|
@@ -35,16 +35,16 @@
|
|
|
35
35
|
"clean": "ts-node --esm scripts/clean.ts"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@hono/node-server": "^1.
|
|
39
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
40
|
-
"@types/node": "^24.0.
|
|
38
|
+
"@hono/node-server": "^1.16.0",
|
|
39
|
+
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
40
|
+
"@types/node": "^24.0.14",
|
|
41
41
|
"@types/sanitize-html": "^2.16.0",
|
|
42
42
|
"@types/validator": "^13.15.2",
|
|
43
43
|
"chrono-node": "2.8.0",
|
|
44
44
|
"dotenv": "16.6.1",
|
|
45
|
-
"hono": "^4.8.
|
|
46
|
-
"jose": "^6.0.
|
|
47
|
-
"openai": "^5.
|
|
45
|
+
"hono": "^4.8.5",
|
|
46
|
+
"jose": "^6.0.12",
|
|
47
|
+
"openai": "^5.9.2",
|
|
48
48
|
"partial-json": "^0.1.7",
|
|
49
49
|
"sanitize-html": "^2.17.0",
|
|
50
50
|
"tiktoken": "^1.0.21",
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
},
|
|
107
107
|
"devDependencies": {
|
|
108
108
|
"prettier": "^3.6.2",
|
|
109
|
-
"typedoc": "^0.28.
|
|
109
|
+
"typedoc": "^0.28.7"
|
|
110
110
|
},
|
|
111
111
|
"publishConfig": {
|
|
112
112
|
"access": "public"
|