@cyanheads/git-mcp-server 2.1.0 → 2.1.2
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 +8 -11
- package/dist/config/index.js +7 -7
- package/dist/index.js +35 -21
- package/dist/mcp-server/server.js +72 -56
- package/dist/mcp-server/tools/gitAdd/index.js +1 -1
- package/dist/mcp-server/tools/gitAdd/logic.js +88 -39
- package/dist/mcp-server/tools/gitAdd/registration.js +17 -14
- package/dist/mcp-server/tools/gitBranch/index.js +1 -1
- package/dist/mcp-server/tools/gitBranch/logic.js +213 -85
- package/dist/mcp-server/tools/gitBranch/registration.js +16 -13
- package/dist/mcp-server/tools/gitCheckout/index.js +1 -1
- package/dist/mcp-server/tools/gitCheckout/logic.js +85 -145
- package/dist/mcp-server/tools/gitCheckout/registration.js +16 -14
- package/dist/mcp-server/tools/gitCherryPick/index.js +1 -1
- package/dist/mcp-server/tools/gitCherryPick/logic.js +100 -41
- package/dist/mcp-server/tools/gitCherryPick/registration.js +21 -14
- package/dist/mcp-server/tools/gitClean/index.js +1 -1
- package/dist/mcp-server/tools/gitClean/logic.js +93 -41
- package/dist/mcp-server/tools/gitClean/registration.js +19 -16
- package/dist/mcp-server/tools/gitClearWorkingDir/index.js +1 -1
- package/dist/mcp-server/tools/gitClearWorkingDir/logic.js +14 -11
- package/dist/mcp-server/tools/gitClearWorkingDir/registration.js +19 -13
- package/dist/mcp-server/tools/gitClone/index.js +1 -1
- package/dist/mcp-server/tools/gitClone/logic.js +89 -30
- package/dist/mcp-server/tools/gitClone/registration.js +15 -12
- package/dist/mcp-server/tools/gitCommit/index.js +1 -1
- package/dist/mcp-server/tools/gitCommit/logic.js +198 -76
- package/dist/mcp-server/tools/gitCommit/registration.js +23 -20
- package/dist/mcp-server/tools/gitDiff/index.js +1 -1
- package/dist/mcp-server/tools/gitDiff/logic.js +124 -44
- package/dist/mcp-server/tools/gitDiff/registration.js +16 -14
- package/dist/mcp-server/tools/gitFetch/index.js +1 -1
- package/dist/mcp-server/tools/gitFetch/logic.js +78 -49
- package/dist/mcp-server/tools/gitFetch/registration.js +16 -14
- package/dist/mcp-server/tools/gitInit/index.js +1 -1
- package/dist/mcp-server/tools/gitInit/logic.js +88 -34
- package/dist/mcp-server/tools/gitInit/registration.js +32 -18
- package/dist/mcp-server/tools/gitLog/index.js +1 -1
- package/dist/mcp-server/tools/gitLog/logic.js +133 -47
- package/dist/mcp-server/tools/gitLog/registration.js +16 -14
- package/dist/mcp-server/tools/gitMerge/index.js +1 -1
- package/dist/mcp-server/tools/gitMerge/logic.js +102 -61
- package/dist/mcp-server/tools/gitMerge/registration.js +17 -14
- package/dist/mcp-server/tools/gitPull/index.js +1 -1
- package/dist/mcp-server/tools/gitPull/logic.js +90 -69
- package/dist/mcp-server/tools/gitPull/registration.js +16 -14
- package/dist/mcp-server/tools/gitPush/index.js +1 -1
- package/dist/mcp-server/tools/gitPush/logic.js +116 -100
- package/dist/mcp-server/tools/gitPush/registration.js +16 -14
- package/dist/mcp-server/tools/gitRebase/index.js +1 -1
- package/dist/mcp-server/tools/gitRebase/logic.js +121 -82
- package/dist/mcp-server/tools/gitRebase/registration.js +21 -14
- package/dist/mcp-server/tools/gitRemote/index.js +1 -1
- package/dist/mcp-server/tools/gitRemote/logic.js +108 -52
- package/dist/mcp-server/tools/gitRemote/registration.js +14 -11
- package/dist/mcp-server/tools/gitReset/index.js +1 -1
- package/dist/mcp-server/tools/gitReset/logic.js +65 -37
- package/dist/mcp-server/tools/gitReset/registration.js +14 -12
- package/dist/mcp-server/tools/gitSetWorkingDir/index.js +1 -1
- package/dist/mcp-server/tools/gitSetWorkingDir/logic.js +74 -34
- package/dist/mcp-server/tools/gitSetWorkingDir/registration.js +18 -11
- package/dist/mcp-server/tools/gitShow/index.js +1 -1
- package/dist/mcp-server/tools/gitShow/logic.js +78 -35
- package/dist/mcp-server/tools/gitShow/registration.js +17 -12
- package/dist/mcp-server/tools/gitStash/index.js +1 -1
- package/dist/mcp-server/tools/gitStash/logic.js +143 -58
- package/dist/mcp-server/tools/gitStash/registration.js +19 -12
- package/dist/mcp-server/tools/gitStatus/index.js +1 -1
- package/dist/mcp-server/tools/gitStatus/logic.js +100 -58
- package/dist/mcp-server/tools/gitStatus/registration.js +15 -12
- package/dist/mcp-server/tools/gitTag/index.js +1 -1
- package/dist/mcp-server/tools/gitTag/logic.js +124 -51
- package/dist/mcp-server/tools/gitTag/registration.js +14 -11
- package/dist/mcp-server/tools/gitWorktree/index.js +1 -1
- package/dist/mcp-server/tools/gitWorktree/logic.js +204 -95
- package/dist/mcp-server/tools/gitWorktree/registration.js +14 -11
- package/dist/mcp-server/tools/gitWrapupInstructions/index.js +1 -1
- package/dist/mcp-server/tools/gitWrapupInstructions/logic.js +23 -11
- package/dist/mcp-server/tools/gitWrapupInstructions/registration.js +14 -12
- package/dist/mcp-server/transports/httpTransport.js +187 -79
- package/dist/mcp-server/transports/stdioTransport.js +14 -8
- package/dist/types-global/errors.js +9 -4
- package/dist/utils/index.js +4 -4
- package/dist/utils/internal/errorHandler.js +62 -40
- package/dist/utils/internal/index.js +3 -3
- package/dist/utils/internal/logger.js +97 -54
- package/dist/utils/internal/requestContext.js +7 -5
- package/dist/utils/metrics/index.js +1 -1
- package/dist/utils/metrics/tokenCounter.js +18 -14
- package/dist/utils/parsing/dateParser.js +5 -5
- package/dist/utils/parsing/index.js +2 -2
- package/dist/utils/parsing/jsonParser.js +20 -11
- package/dist/utils/security/idGenerator.js +8 -10
- package/dist/utils/security/index.js +3 -3
- package/dist/utils/security/rateLimiter.js +16 -14
- package/dist/utils/security/sanitization.js +139 -82
- package/package.json +45 -23
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Git MCP Server
|
|
2
2
|
|
|
3
3
|
[](https://www.typescriptlang.org/)
|
|
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)
|
|
@@ -114,16 +114,13 @@ Add to your MCP client settings (e.g., `cline_mcp_settings.json`):
|
|
|
114
114
|
{
|
|
115
115
|
"mcpServers": {
|
|
116
116
|
"git-mcp-server": {
|
|
117
|
-
|
|
118
|
-
"
|
|
119
|
-
"args": ["/path/to/your/git-mcp-server/dist/index.js"], // Absolute path to the built entry point
|
|
117
|
+
"command": "node",
|
|
118
|
+
"args": ["/path/to/your/git-mcp-server/dist/index.js"],
|
|
120
119
|
"env": {
|
|
121
|
-
|
|
122
|
-
// "MCP_HTTP_PORT": "3010", // Optional: if using http and non-default port
|
|
123
|
-
// "GIT_SIGN_COMMITS": "true" // Optional: Enable commit signing attempts if server is configured
|
|
120
|
+
"GIT_SIGN_COMMITS": "true"
|
|
124
121
|
},
|
|
125
122
|
"disabled": false,
|
|
126
|
-
"autoApprove": []
|
|
123
|
+
"autoApprove": []
|
|
127
124
|
}
|
|
128
125
|
}
|
|
129
126
|
}
|
|
@@ -187,9 +184,9 @@ _Note: The `path` parameter for most tools defaults to the session's working dir
|
|
|
187
184
|
|
|
188
185
|
## Resources
|
|
189
186
|
|
|
190
|
-
**MCP Resources are not implemented in this version (v2.
|
|
187
|
+
**MCP Resources are not implemented in this version (v2.1.2).**
|
|
191
188
|
|
|
192
|
-
This version focuses on the refactored Git tools implementation based on the latest `mcp-ts-template` and MCP SDK v1.12.
|
|
189
|
+
This version focuses on the refactored Git tools implementation based on the latest `mcp-ts-template` and MCP SDK v1.12.3. Resource capabilities, previously available, have been temporarily removed during this major update.
|
|
193
190
|
|
|
194
191
|
If you require MCP Resource access (e.g., for reading file content directly via the server), please use the stable **[v1.2.4 release](https://github.com/cyanheads/git-mcp-server/releases/tag/v1.2.4)**.
|
|
195
192
|
|
package/dist/config/index.js
CHANGED
|
@@ -7,12 +7,12 @@ dotenv.config(); // Load environment variables from .env file
|
|
|
7
7
|
// Determine the directory name of the current module
|
|
8
8
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
9
|
// Construct the path to package.json relative to the current file
|
|
10
|
-
const pkgPath = join(__dirname,
|
|
10
|
+
const pkgPath = join(__dirname, "../../package.json");
|
|
11
11
|
// Default package information in case package.json is unreadable
|
|
12
|
-
let pkg = { name:
|
|
12
|
+
let pkg = { name: "obsidian-mcp-server", version: "0.0.0" };
|
|
13
13
|
try {
|
|
14
14
|
// Read and parse package.json to get server name and version
|
|
15
|
-
pkg = JSON.parse(readFileSync(pkgPath,
|
|
15
|
+
pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
16
16
|
}
|
|
17
17
|
catch (error) {
|
|
18
18
|
// Silently use default pkg info if reading fails. Error will be logged later if needed.
|
|
@@ -37,9 +37,9 @@ export const config = {
|
|
|
37
37
|
/** Host for the HTTP transport. Defaults to '127.0.0.1'. */
|
|
38
38
|
mcpHttpHost: process.env.MCP_HTTP_HOST || "127.0.0.1",
|
|
39
39
|
/** Allowed origins for HTTP transport (comma-separated). */
|
|
40
|
-
mcpAllowedOrigins: process.env.MCP_ALLOWED_ORIGINS?.split(
|
|
40
|
+
mcpAllowedOrigins: process.env.MCP_ALLOWED_ORIGINS?.split(",") || [],
|
|
41
41
|
/** Flag to enable GPG signing for commits made by the git_commit tool. Requires server-side GPG setup. */
|
|
42
|
-
gitSignCommits: process.env.GIT_SIGN_COMMITS ===
|
|
42
|
+
gitSignCommits: process.env.GIT_SIGN_COMMITS === "true",
|
|
43
43
|
/** Security-related configurations. */
|
|
44
44
|
security: {
|
|
45
45
|
// Placeholder for security settings
|
|
@@ -47,8 +47,8 @@ export const config = {
|
|
|
47
47
|
/** Indicates if authentication is required for server operations. */
|
|
48
48
|
authRequired: false,
|
|
49
49
|
/** Secret key for signing/verifying authentication tokens (required if authRequired is true). */
|
|
50
|
-
mcpAuthSecretKey: process.env.MCP_AUTH_SECRET_KEY ||
|
|
51
|
-
}
|
|
50
|
+
mcpAuthSecretKey: process.env.MCP_AUTH_SECRET_KEY || "", // Default to empty string, validation should happen elsewhere
|
|
51
|
+
},
|
|
52
52
|
// Note: mcpClient configuration is now loaded separately from mcp-config.json
|
|
53
53
|
};
|
|
54
54
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { McpServer } from
|
|
3
|
-
import http from
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import http from "http"; // Import http module
|
|
4
4
|
import { config, environment, logLevel } from "./config/index.js"; // Import logLevel from config
|
|
5
5
|
import { initializeAndStartServer } from "./mcp-server/server.js";
|
|
6
6
|
// Import utils from barrel
|
|
7
|
-
import { logger, requestContextService } from
|
|
7
|
+
import { logger, requestContextService } from "./utils/index.js"; // Import McpLogLevel type
|
|
8
8
|
/**
|
|
9
9
|
* The main MCP server instance (used for stdio transport).
|
|
10
10
|
* @type {McpServer | undefined}
|
|
@@ -22,16 +22,16 @@ let httpServerInstance;
|
|
|
22
22
|
* @param signal - The signal or event name that triggered the shutdown (e.g., "SIGTERM", "uncaughtException").
|
|
23
23
|
*/
|
|
24
24
|
const shutdown = async (signal) => {
|
|
25
|
-
const transportType = (process.env.MCP_TRANSPORT_TYPE ||
|
|
25
|
+
const transportType = (process.env.MCP_TRANSPORT_TYPE || "stdio").toLowerCase();
|
|
26
26
|
const shutdownContext = {
|
|
27
|
-
operation:
|
|
27
|
+
operation: "Shutdown",
|
|
28
28
|
signal,
|
|
29
29
|
transport: transportType,
|
|
30
30
|
};
|
|
31
31
|
logger.info(`Received ${signal}. Starting graceful shutdown...`, shutdownContext);
|
|
32
32
|
try {
|
|
33
33
|
let closePromise = Promise.resolve();
|
|
34
|
-
if (transportType ===
|
|
34
|
+
if (transportType === "stdio") {
|
|
35
35
|
// Close the main MCP server instance for stdio
|
|
36
36
|
if (mcpServerInstance) {
|
|
37
37
|
logger.info("Closing main MCP server (stdio)...", shutdownContext);
|
|
@@ -41,14 +41,17 @@ const shutdown = async (signal) => {
|
|
|
41
41
|
logger.warning("Stdio MCP server instance not found during shutdown.", shutdownContext);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
else if (transportType ===
|
|
44
|
+
else if (transportType === "http") {
|
|
45
45
|
// Close the main HTTP server listener for http
|
|
46
46
|
if (httpServerInstance) {
|
|
47
47
|
logger.info("Closing main HTTP server listener...", shutdownContext);
|
|
48
48
|
closePromise = new Promise((resolve, reject) => {
|
|
49
49
|
httpServerInstance.close((err) => {
|
|
50
50
|
if (err) {
|
|
51
|
-
logger.error("Error closing HTTP server listener", {
|
|
51
|
+
logger.error("Error closing HTTP server listener", {
|
|
52
|
+
...shutdownContext,
|
|
53
|
+
error: err.message,
|
|
54
|
+
});
|
|
52
55
|
reject(err);
|
|
53
56
|
}
|
|
54
57
|
else {
|
|
@@ -74,7 +77,7 @@ const shutdown = async (signal) => {
|
|
|
74
77
|
logger.error("Critical error during shutdown", {
|
|
75
78
|
...shutdownContext,
|
|
76
79
|
error: error instanceof Error ? error.message : String(error),
|
|
77
|
-
stack: error instanceof Error ? error.stack : undefined
|
|
80
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
78
81
|
});
|
|
79
82
|
process.exit(1); // Exit with error code if shutdown fails
|
|
80
83
|
}
|
|
@@ -87,8 +90,17 @@ const shutdown = async (signal) => {
|
|
|
87
90
|
const start = async () => {
|
|
88
91
|
// --- Initialize Logger FIRST ---
|
|
89
92
|
// Define valid MCP log levels based on the logger's type definition
|
|
90
|
-
const validMcpLogLevels = [
|
|
91
|
-
|
|
93
|
+
const validMcpLogLevels = [
|
|
94
|
+
"debug",
|
|
95
|
+
"info",
|
|
96
|
+
"notice",
|
|
97
|
+
"warning",
|
|
98
|
+
"error",
|
|
99
|
+
"crit",
|
|
100
|
+
"alert",
|
|
101
|
+
"emerg",
|
|
102
|
+
];
|
|
103
|
+
let validatedMcpLogLevel = "info"; // Default to 'info'
|
|
92
104
|
if (validMcpLogLevels.includes(logLevel)) {
|
|
93
105
|
validatedMcpLogLevel = logLevel;
|
|
94
106
|
}
|
|
@@ -100,12 +112,12 @@ const start = async () => {
|
|
|
100
112
|
logger.initialize(validatedMcpLogLevel);
|
|
101
113
|
// Now it's safe to use the logger.
|
|
102
114
|
// --- Start Application ---
|
|
103
|
-
const transportType = (process.env.MCP_TRANSPORT_TYPE ||
|
|
115
|
+
const transportType = (process.env.MCP_TRANSPORT_TYPE || "stdio").toLowerCase();
|
|
104
116
|
const startupContext = requestContextService.createRequestContext({
|
|
105
117
|
operation: `ServerStartup_${transportType}`, // Include transport in operation name
|
|
106
118
|
appName: config.mcpServerName,
|
|
107
119
|
appVersion: config.mcpServerVersion,
|
|
108
|
-
environment: environment
|
|
120
|
+
environment: environment,
|
|
109
121
|
});
|
|
110
122
|
logger.info(`Starting ${config.mcpServerName} v${config.mcpServerVersion} (Transport: ${transportType})...`, startupContext);
|
|
111
123
|
try {
|
|
@@ -114,11 +126,13 @@ const start = async () => {
|
|
|
114
126
|
// Start the server transport. This returns the McpServer instance for stdio
|
|
115
127
|
// or the http.Server instance for http.
|
|
116
128
|
const serverOrHttpInstance = await initializeAndStartServer();
|
|
117
|
-
if (transportType ===
|
|
129
|
+
if (transportType === "stdio" &&
|
|
130
|
+
serverOrHttpInstance instanceof McpServer) {
|
|
118
131
|
mcpServerInstance = serverOrHttpInstance; // Store McpServer for stdio shutdown
|
|
119
132
|
logger.debug("Stored McpServer instance for stdio transport.", startupContext);
|
|
120
133
|
}
|
|
121
|
-
else if (transportType ===
|
|
134
|
+
else if (transportType === "http" &&
|
|
135
|
+
serverOrHttpInstance instanceof http.Server) {
|
|
122
136
|
httpServerInstance = serverOrHttpInstance; // Store http.Server for http shutdown
|
|
123
137
|
logger.debug("Stored http.Server instance for http transport.", startupContext);
|
|
124
138
|
}
|
|
@@ -126,7 +140,7 @@ const start = async () => {
|
|
|
126
140
|
// This case should ideally not happen if initializeAndStartServer works correctly
|
|
127
141
|
logger.warning("initializeAndStartServer did not return the expected instance type.", {
|
|
128
142
|
...startupContext,
|
|
129
|
-
instanceType: typeof serverOrHttpInstance
|
|
143
|
+
instanceType: typeof serverOrHttpInstance,
|
|
130
144
|
});
|
|
131
145
|
}
|
|
132
146
|
// If initializeAndStartServer failed internally, it would have thrown an error,
|
|
@@ -143,9 +157,9 @@ const start = async () => {
|
|
|
143
157
|
process.on("uncaughtException", async (error) => {
|
|
144
158
|
const errorContext = {
|
|
145
159
|
...startupContext, // Include base context for correlation
|
|
146
|
-
event:
|
|
160
|
+
event: "uncaughtException",
|
|
147
161
|
error: error instanceof Error ? error.message : String(error),
|
|
148
|
-
stack: error instanceof Error ? error.stack : undefined
|
|
162
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
149
163
|
};
|
|
150
164
|
logger.error("Uncaught exception detected. Initiating shutdown...", errorContext);
|
|
151
165
|
// Attempt graceful shutdown; shutdown() handles its own errors.
|
|
@@ -159,9 +173,9 @@ const start = async () => {
|
|
|
159
173
|
process.on("unhandledRejection", async (reason) => {
|
|
160
174
|
const rejectionContext = {
|
|
161
175
|
...startupContext, // Include base context for correlation
|
|
162
|
-
event:
|
|
176
|
+
event: "unhandledRejection",
|
|
163
177
|
reason: reason instanceof Error ? reason.message : String(reason),
|
|
164
|
-
stack: reason instanceof Error ? reason.stack : undefined
|
|
178
|
+
stack: reason instanceof Error ? reason.stack : undefined,
|
|
165
179
|
};
|
|
166
180
|
logger.error("Unhandled promise rejection detected. Initiating shutdown...", rejectionContext);
|
|
167
181
|
// Attempt graceful shutdown; shutdown() handles its own errors.
|
|
@@ -174,7 +188,7 @@ const start = async () => {
|
|
|
174
188
|
// Log the final failure context, including error details, before exiting
|
|
175
189
|
logger.error("Critical error during startup, exiting.", {
|
|
176
190
|
...startupContext,
|
|
177
|
-
finalErrorContext:
|
|
191
|
+
finalErrorContext: "Startup Failure",
|
|
178
192
|
error: error instanceof Error ? error.message : String(error),
|
|
179
193
|
stack: error instanceof Error ? error.stack : undefined,
|
|
180
194
|
});
|
|
@@ -12,40 +12,40 @@
|
|
|
12
12
|
* - Overview (Capabilities): https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-03-26/basic/index.mdx
|
|
13
13
|
* - Transports: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-03-26/basic/transports.mdx
|
|
14
14
|
*/
|
|
15
|
-
import { McpServer } from
|
|
15
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
16
16
|
// Import validated configuration and environment details.
|
|
17
|
-
import { config, environment } from
|
|
17
|
+
import { config, environment } from "../config/index.js";
|
|
18
18
|
// Import core utilities: ErrorHandler, logger, requestContextService.
|
|
19
|
-
import { ErrorHandler, logger, requestContextService } from
|
|
19
|
+
import { ErrorHandler, logger, requestContextService, } from "../utils/index.js"; // Added RequestContext
|
|
20
20
|
// Import registration AND state initialization functions for ALL Git tools (alphabetized)
|
|
21
|
-
import { initializeGitAddStateAccessors, registerGitAddTool } from
|
|
22
|
-
import { initializeGitBranchStateAccessors, registerGitBranchTool } from
|
|
23
|
-
import { initializeGitCheckoutStateAccessors, registerGitCheckoutTool } from
|
|
24
|
-
import { initializeGitCherryPickStateAccessors, registerGitCherryPickTool } from
|
|
25
|
-
import { initializeGitCleanStateAccessors, registerGitCleanTool } from
|
|
26
|
-
import { initializeGitClearWorkingDirStateAccessors, registerGitClearWorkingDirTool } from
|
|
27
|
-
import { registerGitCloneTool } from
|
|
28
|
-
import { initializeGitCommitStateAccessors, registerGitCommitTool } from
|
|
29
|
-
import { initializeGitDiffStateAccessors, registerGitDiffTool } from
|
|
30
|
-
import { initializeGitFetchStateAccessors, registerGitFetchTool } from
|
|
31
|
-
import { initializeGitInitStateAccessors, registerGitInitTool } from
|
|
32
|
-
import { initializeGitLogStateAccessors, registerGitLogTool } from
|
|
33
|
-
import { initializeGitMergeStateAccessors, registerGitMergeTool } from
|
|
34
|
-
import { initializeGitPullStateAccessors, registerGitPullTool } from
|
|
35
|
-
import { initializeGitPushStateAccessors, registerGitPushTool } from
|
|
36
|
-
import { initializeGitRebaseStateAccessors, registerGitRebaseTool } from
|
|
37
|
-
import { initializeGitRemoteStateAccessors, registerGitRemoteTool } from
|
|
38
|
-
import { initializeGitResetStateAccessors, registerGitResetTool } from
|
|
39
|
-
import { initializeGitSetWorkingDirStateAccessors, registerGitSetWorkingDirTool } from
|
|
40
|
-
import { initializeGitShowStateAccessors, registerGitShowTool } from
|
|
41
|
-
import { initializeGitStashStateAccessors, registerGitStashTool } from
|
|
42
|
-
import { initializeGitStatusStateAccessors, registerGitStatusTool } from
|
|
43
|
-
import { initializeGitTagStateAccessors, registerGitTagTool } from
|
|
44
|
-
import { initializeGitWorktreeStateAccessors, registerGitWorktreeTool } from
|
|
45
|
-
import { initializeGitWrapupInstructionsStateAccessors, registerGitWrapupInstructionsTool } from
|
|
21
|
+
import { initializeGitAddStateAccessors, registerGitAddTool, } from "./tools/gitAdd/index.js";
|
|
22
|
+
import { initializeGitBranchStateAccessors, registerGitBranchTool, } from "./tools/gitBranch/index.js";
|
|
23
|
+
import { initializeGitCheckoutStateAccessors, registerGitCheckoutTool, } from "./tools/gitCheckout/index.js";
|
|
24
|
+
import { initializeGitCherryPickStateAccessors, registerGitCherryPickTool, } from "./tools/gitCherryPick/index.js";
|
|
25
|
+
import { initializeGitCleanStateAccessors, registerGitCleanTool, } from "./tools/gitClean/index.js";
|
|
26
|
+
import { initializeGitClearWorkingDirStateAccessors, registerGitClearWorkingDirTool, } from "./tools/gitClearWorkingDir/index.js";
|
|
27
|
+
import { registerGitCloneTool } from "./tools/gitClone/index.js"; // No initializer needed/available
|
|
28
|
+
import { initializeGitCommitStateAccessors, registerGitCommitTool, } from "./tools/gitCommit/index.js";
|
|
29
|
+
import { initializeGitDiffStateAccessors, registerGitDiffTool, } from "./tools/gitDiff/index.js";
|
|
30
|
+
import { initializeGitFetchStateAccessors, registerGitFetchTool, } from "./tools/gitFetch/index.js";
|
|
31
|
+
import { initializeGitInitStateAccessors, registerGitInitTool, } from "./tools/gitInit/index.js";
|
|
32
|
+
import { initializeGitLogStateAccessors, registerGitLogTool, } from "./tools/gitLog/index.js";
|
|
33
|
+
import { initializeGitMergeStateAccessors, registerGitMergeTool, } from "./tools/gitMerge/index.js";
|
|
34
|
+
import { initializeGitPullStateAccessors, registerGitPullTool, } from "./tools/gitPull/index.js";
|
|
35
|
+
import { initializeGitPushStateAccessors, registerGitPushTool, } from "./tools/gitPush/index.js";
|
|
36
|
+
import { initializeGitRebaseStateAccessors, registerGitRebaseTool, } from "./tools/gitRebase/index.js";
|
|
37
|
+
import { initializeGitRemoteStateAccessors, registerGitRemoteTool, } from "./tools/gitRemote/index.js";
|
|
38
|
+
import { initializeGitResetStateAccessors, registerGitResetTool, } from "./tools/gitReset/index.js";
|
|
39
|
+
import { initializeGitSetWorkingDirStateAccessors, registerGitSetWorkingDirTool, } from "./tools/gitSetWorkingDir/index.js";
|
|
40
|
+
import { initializeGitShowStateAccessors, registerGitShowTool, } from "./tools/gitShow/index.js";
|
|
41
|
+
import { initializeGitStashStateAccessors, registerGitStashTool, } from "./tools/gitStash/index.js";
|
|
42
|
+
import { initializeGitStatusStateAccessors, registerGitStatusTool, } from "./tools/gitStatus/index.js";
|
|
43
|
+
import { initializeGitTagStateAccessors, registerGitTagTool, } from "./tools/gitTag/index.js";
|
|
44
|
+
import { initializeGitWorktreeStateAccessors, registerGitWorktreeTool, } from "./tools/gitWorktree/index.js";
|
|
45
|
+
import { initializeGitWrapupInstructionsStateAccessors, registerGitWrapupInstructionsTool, } from "./tools/gitWrapupInstructions/index.js";
|
|
46
46
|
// Import transport setup functions AND state accessors
|
|
47
|
-
import { getHttpSessionWorkingDirectory, setHttpSessionWorkingDirectory, startHttpTransport } from
|
|
48
|
-
import { connectStdioTransport, getStdioWorkingDirectory, setStdioWorkingDirectory } from
|
|
47
|
+
import { getHttpSessionWorkingDirectory, setHttpSessionWorkingDirectory, startHttpTransport, } from "./transports/httpTransport.js";
|
|
48
|
+
import { connectStdioTransport, getStdioWorkingDirectory, setStdioWorkingDirectory, } from "./transports/stdioTransport.js";
|
|
49
49
|
/**
|
|
50
50
|
* Creates and configures a new instance of the McpServer.
|
|
51
51
|
*
|
|
@@ -79,8 +79,8 @@ import { connectStdioTransport, getStdioWorkingDirectory, setStdioWorkingDirecto
|
|
|
79
79
|
*/
|
|
80
80
|
// Removed sessionId parameter, it will be retrieved from context within tool handlers
|
|
81
81
|
async function createMcpServerInstance() {
|
|
82
|
-
const context = { operation:
|
|
83
|
-
logger.info(
|
|
82
|
+
const context = { operation: "createMcpServerInstance" };
|
|
83
|
+
logger.info("Initializing MCP server instance", context);
|
|
84
84
|
// Configure the request context service (used for correlating logs/errors).
|
|
85
85
|
requestContextService.configure({
|
|
86
86
|
appName: config.mcpServerName,
|
|
@@ -90,10 +90,26 @@ async function createMcpServerInstance() {
|
|
|
90
90
|
// Instantiate the core McpServer using the SDK.
|
|
91
91
|
// Provide server identity (name, version) and declare supported capabilities.
|
|
92
92
|
// Note: Resources capability declared, but none are registered currently.
|
|
93
|
-
logger.debug(
|
|
93
|
+
logger.debug("Instantiating McpServer with capabilities", {
|
|
94
|
+
...context,
|
|
95
|
+
serverInfo: {
|
|
96
|
+
name: config.mcpServerName,
|
|
97
|
+
version: config.mcpServerVersion,
|
|
98
|
+
},
|
|
99
|
+
capabilities: {
|
|
100
|
+
logging: {},
|
|
101
|
+
resources: { listChanged: true },
|
|
102
|
+
tools: { listChanged: true },
|
|
103
|
+
},
|
|
104
|
+
});
|
|
94
105
|
const server = new McpServer({ name: config.mcpServerName, version: config.mcpServerVersion }, // ServerInformation part of InitializeResult
|
|
95
|
-
{
|
|
96
|
-
|
|
106
|
+
{
|
|
107
|
+
capabilities: {
|
|
108
|
+
logging: {},
|
|
109
|
+
resources: { listChanged: true },
|
|
110
|
+
tools: { listChanged: true },
|
|
111
|
+
},
|
|
112
|
+
});
|
|
97
113
|
// --- Define Unified State Accessor Functions ---
|
|
98
114
|
// These functions abstract away the transport type to get/set session state.
|
|
99
115
|
/** Gets the session ID from the tool's execution context. */
|
|
@@ -103,9 +119,9 @@ async function createMcpServerInstance() {
|
|
|
103
119
|
};
|
|
104
120
|
/** Gets the working directory based on transport type and session ID. */
|
|
105
121
|
const getWorkingDirectory = (sessionId) => {
|
|
106
|
-
if (config.mcpTransportType ===
|
|
122
|
+
if (config.mcpTransportType === "http") {
|
|
107
123
|
if (!sessionId) {
|
|
108
|
-
logger.warning(
|
|
124
|
+
logger.warning("Attempted to get HTTP working directory without session ID", { ...context, caller: "getWorkingDirectory" });
|
|
109
125
|
return undefined;
|
|
110
126
|
}
|
|
111
127
|
return getHttpSessionWorkingDirectory(sessionId);
|
|
@@ -117,9 +133,9 @@ async function createMcpServerInstance() {
|
|
|
117
133
|
};
|
|
118
134
|
/** Sets the working directory based on transport type and session ID. */
|
|
119
135
|
const setWorkingDirectory = (sessionId, dir) => {
|
|
120
|
-
if (config.mcpTransportType ===
|
|
136
|
+
if (config.mcpTransportType === "http") {
|
|
121
137
|
if (!sessionId) {
|
|
122
|
-
logger.error(
|
|
138
|
+
logger.error("Attempted to set HTTP working directory without session ID", { ...context, caller: "setWorkingDirectory", dir });
|
|
123
139
|
// Optionally throw an error or just log
|
|
124
140
|
return;
|
|
125
141
|
}
|
|
@@ -132,7 +148,7 @@ async function createMcpServerInstance() {
|
|
|
132
148
|
};
|
|
133
149
|
// --- Initialize Tool State Accessors BEFORE Registration ---
|
|
134
150
|
// Pass the defined unified accessor functions to the initializers.
|
|
135
|
-
logger.debug(
|
|
151
|
+
logger.debug("Initializing state accessors for tools...", context);
|
|
136
152
|
try {
|
|
137
153
|
// Call initializers for all tools that likely need state access (alphabetized).
|
|
138
154
|
// If an initializer doesn't exist, the import would have failed earlier (or build will fail).
|
|
@@ -161,11 +177,11 @@ async function createMcpServerInstance() {
|
|
|
161
177
|
initializeGitTagStateAccessors(getWorkingDirectory, getSessionIdFromContext);
|
|
162
178
|
initializeGitWorktreeStateAccessors(getWorkingDirectory, getSessionIdFromContext);
|
|
163
179
|
initializeGitWrapupInstructionsStateAccessors(getWorkingDirectory, getSessionIdFromContext); // Added this line
|
|
164
|
-
logger.debug(
|
|
180
|
+
logger.debug("State accessors initialized successfully.", context);
|
|
165
181
|
}
|
|
166
182
|
catch (initError) {
|
|
167
183
|
// Catch errors specifically during initialization phase
|
|
168
|
-
logger.error(
|
|
184
|
+
logger.error("Failed during state accessor initialization", {
|
|
169
185
|
...context,
|
|
170
186
|
error: initError instanceof Error ? initError.message : String(initError),
|
|
171
187
|
stack: initError instanceof Error ? initError.stack : undefined,
|
|
@@ -175,7 +191,7 @@ async function createMcpServerInstance() {
|
|
|
175
191
|
try {
|
|
176
192
|
// Register all defined Git tools (alphabetized). These calls populate the server's
|
|
177
193
|
// internal registry, making them available via MCP methods like 'tools/list'.
|
|
178
|
-
logger.debug(
|
|
194
|
+
logger.debug("Registering Git tools...", context);
|
|
179
195
|
await registerGitAddTool(server);
|
|
180
196
|
await registerGitBranchTool(server);
|
|
181
197
|
await registerGitCheckoutTool(server);
|
|
@@ -202,11 +218,11 @@ async function createMcpServerInstance() {
|
|
|
202
218
|
await registerGitWorktreeTool(server);
|
|
203
219
|
await registerGitWrapupInstructionsTool(server);
|
|
204
220
|
// Add calls to register other resources/tools here if needed in the future.
|
|
205
|
-
logger.info(
|
|
221
|
+
logger.info("Git tools registered successfully", context);
|
|
206
222
|
}
|
|
207
223
|
catch (err) {
|
|
208
224
|
// Registration is critical; log and re-throw errors.
|
|
209
|
-
logger.error(
|
|
225
|
+
logger.error("Failed to register resources/tools", {
|
|
210
226
|
...context,
|
|
211
227
|
error: err instanceof Error ? err.message : String(err),
|
|
212
228
|
stack: err instanceof Error ? err.stack : undefined, // Include stack for debugging
|
|
@@ -238,11 +254,11 @@ async function createMcpServerInstance() {
|
|
|
238
254
|
async function startTransport() {
|
|
239
255
|
// Determine the transport type from the validated configuration.
|
|
240
256
|
const transportType = config.mcpTransportType;
|
|
241
|
-
const context = { operation:
|
|
257
|
+
const context = { operation: "startTransport", transport: transportType };
|
|
242
258
|
logger.info(`Starting transport: ${transportType}`, context);
|
|
243
259
|
// --- HTTP Transport Setup ---
|
|
244
|
-
if (transportType ===
|
|
245
|
-
logger.debug(
|
|
260
|
+
if (transportType === "http") {
|
|
261
|
+
logger.debug("Delegating to startHttpTransport...", context);
|
|
246
262
|
// For HTTP, the transport layer manages its own lifecycle and potentially multiple sessions.
|
|
247
263
|
// We pass the factory function to allow the HTTP transport to create server instances as needed (per session).
|
|
248
264
|
await startHttpTransport(createMcpServerInstance, context);
|
|
@@ -250,12 +266,12 @@ async function startTransport() {
|
|
|
250
266
|
return;
|
|
251
267
|
}
|
|
252
268
|
// --- Stdio Transport Setup ---
|
|
253
|
-
if (transportType ===
|
|
254
|
-
logger.debug(
|
|
269
|
+
if (transportType === "stdio") {
|
|
270
|
+
logger.debug("Creating single McpServer instance for stdio transport...", context);
|
|
255
271
|
// For stdio, there's typically one persistent connection managed by a parent process.
|
|
256
272
|
// Create a single McpServer instance for the entire process lifetime.
|
|
257
273
|
const server = await createMcpServerInstance();
|
|
258
|
-
logger.debug(
|
|
274
|
+
logger.debug("Delegating to connectStdioTransport...", context);
|
|
259
275
|
// Connect the server instance to the stdio transport handler.
|
|
260
276
|
await connectStdioTransport(server, context);
|
|
261
277
|
// Return the server instance; the caller (main entry point) might hold onto it.
|
|
@@ -278,17 +294,17 @@ async function startTransport() {
|
|
|
278
294
|
* @returns {Promise<void | McpServer>} Resolves upon successful startup (void for http, McpServer for stdio). Rejects on critical failure.
|
|
279
295
|
*/
|
|
280
296
|
export async function initializeAndStartServer() {
|
|
281
|
-
const context = { operation:
|
|
282
|
-
logger.info(
|
|
297
|
+
const context = { operation: "initializeAndStartServer" };
|
|
298
|
+
logger.info("MCP Server initialization sequence started.", context);
|
|
283
299
|
try {
|
|
284
300
|
// Initiate the transport setup based on configuration.
|
|
285
301
|
const result = await startTransport();
|
|
286
|
-
logger.info(
|
|
302
|
+
logger.info("MCP Server initialization sequence completed successfully.", context);
|
|
287
303
|
return result;
|
|
288
304
|
}
|
|
289
305
|
catch (err) {
|
|
290
306
|
// Catch any errors that occurred during server instance creation or transport setup.
|
|
291
|
-
logger.fatal(
|
|
307
|
+
logger.fatal("Critical error during MCP server initialization.", {
|
|
292
308
|
...context,
|
|
293
309
|
error: err instanceof Error ? err.message : String(err),
|
|
294
310
|
stack: err instanceof Error ? err.stack : undefined,
|
|
@@ -296,7 +312,7 @@ export async function initializeAndStartServer() {
|
|
|
296
312
|
// Use the centralized error handler for consistent critical error reporting.
|
|
297
313
|
ErrorHandler.handleError(err, { ...context, critical: true });
|
|
298
314
|
// Exit the process with a non-zero code to indicate failure.
|
|
299
|
-
logger.info(
|
|
315
|
+
logger.info("Exiting process due to critical initialization error.", context);
|
|
300
316
|
process.exit(1);
|
|
301
317
|
}
|
|
302
318
|
}
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* @fileoverview Barrel file for the gitAdd tool.
|
|
3
3
|
* Exports the registration function and state accessor initialization function.
|
|
4
4
|
*/
|
|
5
|
-
export { registerGitAddTool, initializeGitAddStateAccessors } from
|
|
5
|
+
export { registerGitAddTool, initializeGitAddStateAccessors, } from "./registration.js";
|
|
6
6
|
// Export types if needed elsewhere, e.g.:
|
|
7
7
|
// export type { GitAddInput, GitAddResult } from './logic.js';
|