@cyanheads/git-mcp-server 2.0.7 → 2.0.8
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 +1 -1
- package/dist/mcp-server/tools/gitAdd/logic.js +1 -1
- package/dist/mcp-server/tools/gitBranch/logic.js +1 -1
- package/dist/mcp-server/tools/gitCheckout/logic.js +1 -1
- package/dist/mcp-server/tools/gitCherryPick/logic.js +1 -1
- package/dist/mcp-server/tools/gitClean/logic.js +1 -1
- package/dist/mcp-server/tools/gitClone/logic.js +1 -1
- package/dist/mcp-server/tools/gitCommit/logic.js +1 -1
- package/dist/mcp-server/tools/gitDiff/logic.js +1 -1
- package/dist/mcp-server/tools/gitFetch/logic.js +1 -1
- package/dist/mcp-server/tools/gitInit/logic.js +1 -1
- package/dist/mcp-server/tools/gitInit/registration.js +2 -2
- package/dist/mcp-server/tools/gitLog/logic.js +1 -1
- package/dist/mcp-server/tools/gitPull/logic.js +1 -1
- package/dist/mcp-server/tools/gitPush/logic.js +1 -1
- package/dist/mcp-server/tools/gitRebase/logic.js +1 -1
- package/dist/mcp-server/tools/gitRemote/logic.js +1 -1
- package/dist/mcp-server/tools/gitReset/logic.js +1 -1
- package/dist/mcp-server/tools/gitSetWorkingDir/logic.js +2 -2
- package/dist/mcp-server/tools/gitShow/logic.js +1 -1
- package/dist/mcp-server/tools/gitStash/logic.js +1 -1
- package/dist/mcp-server/tools/gitStatus/logic.js +1 -1
- package/dist/mcp-server/tools/gitTag/logic.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.typescriptlang.org/)
|
|
4
4
|
[](https://modelcontextprotocol.io/)
|
|
5
|
-
[](./CHANGELOG.md)
|
|
6
6
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
7
7
|
[](https://github.com/cyanheads/git-mcp-server/issues)
|
|
8
8
|
[](https://github.com/cyanheads/git-mcp-server)
|
|
@@ -44,7 +44,7 @@ export async function addGitFiles(input, context // Add getter to context
|
|
|
44
44
|
logger.debug(`Using session working directory: ${targetPath}`, { ...context, operation, sessionId: context.sessionId });
|
|
45
45
|
}
|
|
46
46
|
// Sanitize the resolved path
|
|
47
|
-
const sanitizedPath = sanitization.sanitizePath(targetPath);
|
|
47
|
+
const sanitizedPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
48
48
|
logger.debug('Sanitized repository path', { ...context, operation, sanitizedPath });
|
|
49
49
|
targetPath = sanitizedPath; // Use the sanitized path going forward
|
|
50
50
|
}
|
|
@@ -56,7 +56,7 @@ export async function gitBranchLogic(input, context) {
|
|
|
56
56
|
else {
|
|
57
57
|
logger.debug(`Using provided path: ${targetPath}`, { ...context, operation });
|
|
58
58
|
}
|
|
59
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
59
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
60
60
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
61
61
|
}
|
|
62
62
|
catch (error) {
|
|
@@ -41,7 +41,7 @@ export async function checkoutGit(input, context) {
|
|
|
41
41
|
}
|
|
42
42
|
targetPath = workingDir;
|
|
43
43
|
}
|
|
44
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
44
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
45
45
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
46
46
|
}
|
|
47
47
|
catch (error) {
|
|
@@ -47,7 +47,7 @@ export async function gitCherryPickLogic(input, context) {
|
|
|
47
47
|
else {
|
|
48
48
|
logger.debug(`Using provided path: ${targetPath}`, { ...context, operation });
|
|
49
49
|
}
|
|
50
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
50
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
51
51
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
52
52
|
}
|
|
53
53
|
catch (error) {
|
|
@@ -55,7 +55,7 @@ export async function gitCleanLogic(input, context) {
|
|
|
55
55
|
else {
|
|
56
56
|
logger.debug(`Using provided path: ${targetPath}`, { ...context, operation });
|
|
57
57
|
}
|
|
58
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
58
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
59
59
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
60
60
|
}
|
|
61
61
|
catch (error) {
|
|
@@ -33,7 +33,7 @@ export async function gitCloneLogic(input, context) {
|
|
|
33
33
|
let sanitizedRepoUrl;
|
|
34
34
|
try {
|
|
35
35
|
// Sanitize the target path (must be absolute)
|
|
36
|
-
sanitizedTargetPath = sanitization.sanitizePath(input.targetPath);
|
|
36
|
+
sanitizedTargetPath = sanitization.sanitizePath(input.targetPath, { allowAbsolute: true });
|
|
37
37
|
logger.debug('Sanitized target path', { ...context, operation, sanitizedTargetPath });
|
|
38
38
|
// Basic sanitization/validation for URL (Zod already checks format)
|
|
39
39
|
// Further sanitization might be needed depending on how it's used in the shell command
|
|
@@ -50,7 +50,7 @@ export async function commitGitChanges(input, context // Add getter to context
|
|
|
50
50
|
logger.debug(`Using session working directory: ${targetPath}`, { ...context, operation, sessionId: context.sessionId });
|
|
51
51
|
}
|
|
52
52
|
// Sanitize the resolved path
|
|
53
|
-
const sanitizedPath = sanitization.sanitizePath(targetPath);
|
|
53
|
+
const sanitizedPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
54
54
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath });
|
|
55
55
|
targetPath = sanitizedPath; // Use the sanitized path going forward
|
|
56
56
|
}
|
|
@@ -48,7 +48,7 @@ export async function diffGitChanges(input, context) {
|
|
|
48
48
|
}
|
|
49
49
|
targetPath = workingDir;
|
|
50
50
|
}
|
|
51
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
51
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
52
52
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
53
53
|
}
|
|
54
54
|
catch (error) {
|
|
@@ -41,7 +41,7 @@ export async function fetchGitRemote(input, context) {
|
|
|
41
41
|
}
|
|
42
42
|
targetPath = workingDir;
|
|
43
43
|
}
|
|
44
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
44
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
45
45
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
46
46
|
}
|
|
47
47
|
catch (error) {
|
|
@@ -31,7 +31,7 @@ export async function gitInitLogic(input, context) {
|
|
|
31
31
|
let targetPath;
|
|
32
32
|
try {
|
|
33
33
|
// Sanitize the provided absolute path
|
|
34
|
-
targetPath = sanitization.sanitizePath(input.path);
|
|
34
|
+
targetPath = sanitization.sanitizePath(input.path, { allowAbsolute: true });
|
|
35
35
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
36
36
|
// Ensure the target directory exists before trying to init inside it
|
|
37
37
|
// git init creates the directory if it doesn't exist, but we might want to ensure the parent exists
|
|
@@ -55,11 +55,11 @@ export const registerGitInitTool = async (server) => {
|
|
|
55
55
|
let resolvedPath;
|
|
56
56
|
try {
|
|
57
57
|
if (path.isAbsolute(inputPath)) {
|
|
58
|
-
resolvedPath = sanitization.sanitizePath(inputPath);
|
|
58
|
+
resolvedPath = sanitization.sanitizePath(inputPath, { allowAbsolute: true });
|
|
59
59
|
logger.debug(`Using absolute path: ${resolvedPath}`, requestContext);
|
|
60
60
|
}
|
|
61
61
|
else if (sessionWorkingDirectory) {
|
|
62
|
-
resolvedPath = sanitization.sanitizePath(path.resolve(sessionWorkingDirectory, inputPath));
|
|
62
|
+
resolvedPath = sanitization.sanitizePath(path.resolve(sessionWorkingDirectory, inputPath), { allowAbsolute: true });
|
|
63
63
|
logger.debug(`Resolved relative path '${inputPath}' to absolute path: ${resolvedPath} using session CWD`, requestContext);
|
|
64
64
|
}
|
|
65
65
|
else {
|
|
@@ -56,7 +56,7 @@ export async function logGitHistory(input, context) {
|
|
|
56
56
|
}
|
|
57
57
|
targetPath = workingDir;
|
|
58
58
|
}
|
|
59
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
59
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
60
60
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
61
61
|
}
|
|
62
62
|
catch (error) {
|
|
@@ -44,7 +44,7 @@ export async function pullGitChanges(input, context) {
|
|
|
44
44
|
logger.debug(`Using session working directory: ${targetPath}`, { ...context, operation, sessionId: context.sessionId });
|
|
45
45
|
}
|
|
46
46
|
// Sanitize the resolved path
|
|
47
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
47
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
48
48
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
49
49
|
}
|
|
50
50
|
catch (error) {
|
|
@@ -45,7 +45,7 @@ export async function pushGitChanges(input, context) {
|
|
|
45
45
|
}
|
|
46
46
|
targetPath = workingDir;
|
|
47
47
|
}
|
|
48
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
48
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
49
49
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
50
50
|
}
|
|
51
51
|
catch (error) {
|
|
@@ -55,7 +55,7 @@ export async function gitRebaseLogic(input, context) {
|
|
|
55
55
|
else {
|
|
56
56
|
logger.debug(`Using provided path: ${targetPath}`, { ...context, operation });
|
|
57
57
|
}
|
|
58
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
58
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
59
59
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
60
60
|
}
|
|
61
61
|
catch (error) {
|
|
@@ -42,7 +42,7 @@ export async function gitRemoteLogic(input, context) {
|
|
|
42
42
|
else {
|
|
43
43
|
logger.debug(`Using provided path: ${targetPath}`, { ...context, operation });
|
|
44
44
|
}
|
|
45
|
-
targetPath = sanitization.sanitizePath(targetPath); // Sanitize the final resolved path
|
|
45
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true }); // Sanitize the final resolved path
|
|
46
46
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
47
47
|
}
|
|
48
48
|
catch (error) {
|
|
@@ -44,7 +44,7 @@ export async function resetGitState(input, context) {
|
|
|
44
44
|
}
|
|
45
45
|
targetPath = workingDir;
|
|
46
46
|
}
|
|
47
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
47
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
48
48
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
49
49
|
}
|
|
50
50
|
catch (error) {
|
|
@@ -26,9 +26,9 @@ export async function gitSetWorkingDirLogic(input, context // Assuming context p
|
|
|
26
26
|
logger.info('Executing git_set_working_dir logic', { ...context, operation, inputPath: input.path });
|
|
27
27
|
let sanitizedPath;
|
|
28
28
|
try {
|
|
29
|
-
// Sanitize the path.
|
|
29
|
+
// Sanitize the path. Must explicitly allow absolute paths for this tool.
|
|
30
30
|
// It normalizes and checks for traversal issues.
|
|
31
|
-
sanitizedPath = sanitization.sanitizePath(input.path);
|
|
31
|
+
sanitizedPath = sanitization.sanitizePath(input.path, { allowAbsolute: true });
|
|
32
32
|
logger.debug(`Sanitized path: ${sanitizedPath}`, { ...context, operation });
|
|
33
33
|
}
|
|
34
34
|
catch (error) {
|
|
@@ -41,7 +41,7 @@ export async function gitShowLogic(input, context) {
|
|
|
41
41
|
else {
|
|
42
42
|
logger.debug(`Using provided path: ${targetPath}`, { ...context, operation });
|
|
43
43
|
}
|
|
44
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
44
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
45
45
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
46
46
|
}
|
|
47
47
|
catch (error) {
|
|
@@ -47,7 +47,7 @@ export async function gitStashLogic(input, context) {
|
|
|
47
47
|
else {
|
|
48
48
|
logger.debug(`Using provided path: ${targetPath}`, { ...context, operation });
|
|
49
49
|
}
|
|
50
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
50
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
51
51
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
52
52
|
}
|
|
53
53
|
catch (error) {
|
|
@@ -160,7 +160,7 @@ export async function getGitStatus(input, context // Add getter to context
|
|
|
160
160
|
logger.debug(`Using session working directory: ${targetPath}`, { ...context, operation, sessionId: context.sessionId });
|
|
161
161
|
}
|
|
162
162
|
// Sanitize the resolved path
|
|
163
|
-
const sanitizedPath = sanitization.sanitizePath(targetPath);
|
|
163
|
+
const sanitizedPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
164
164
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath });
|
|
165
165
|
targetPath = sanitizedPath; // Use the sanitized path going forward
|
|
166
166
|
}
|
|
@@ -55,7 +55,7 @@ export async function gitTagLogic(input, context) {
|
|
|
55
55
|
else {
|
|
56
56
|
logger.debug(`Using provided path: ${targetPath}`, { ...context, operation });
|
|
57
57
|
}
|
|
58
|
-
targetPath = sanitization.sanitizePath(targetPath);
|
|
58
|
+
targetPath = sanitization.sanitizePath(targetPath, { allowAbsolute: true });
|
|
59
59
|
logger.debug('Sanitized path', { ...context, operation, sanitizedPath: targetPath });
|
|
60
60
|
}
|
|
61
61
|
catch (error) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/git-mcp-server",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.8",
|
|
4
4
|
"description": "An MCP (Model Context Protocol) server providing tools to interact with Git repositories. Enables LLMs and AI agents to perform Git operations like clone, commit, push, pull, branch, diff, log, status, and more via the MCP standard.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@modelcontextprotocol/sdk": "^1.11.0",
|
|
40
40
|
"@types/jsonwebtoken": "^9.0.9",
|
|
41
|
-
"@types/node": "^22.15.
|
|
41
|
+
"@types/node": "^22.15.15",
|
|
42
42
|
"@types/sanitize-html": "^2.16.0",
|
|
43
43
|
"@types/validator": "^13.15.0",
|
|
44
44
|
"chrono-node": "^2.8.0",
|