@cyanheads/git-mcp-server 2.0.2 → 2.0.4

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.
Files changed (73) hide show
  1. package/README.md +45 -85
  2. package/dist/config/index.js +16 -18
  3. package/dist/index.js +80 -30
  4. package/dist/mcp-server/server.js +247 -523
  5. package/dist/mcp-server/tools/gitAdd/logic.js +9 -6
  6. package/dist/mcp-server/tools/gitAdd/registration.js +7 -4
  7. package/dist/mcp-server/tools/gitBranch/logic.js +23 -12
  8. package/dist/mcp-server/tools/gitBranch/registration.js +8 -5
  9. package/dist/mcp-server/tools/gitCheckout/logic.js +92 -44
  10. package/dist/mcp-server/tools/gitCheckout/registration.js +8 -5
  11. package/dist/mcp-server/tools/gitCherryPick/logic.js +10 -7
  12. package/dist/mcp-server/tools/gitCherryPick/registration.js +8 -5
  13. package/dist/mcp-server/tools/gitClean/logic.js +9 -6
  14. package/dist/mcp-server/tools/gitClean/registration.js +8 -5
  15. package/dist/mcp-server/tools/gitClearWorkingDir/logic.js +3 -2
  16. package/dist/mcp-server/tools/gitClearWorkingDir/registration.js +7 -4
  17. package/dist/mcp-server/tools/gitClone/logic.js +8 -5
  18. package/dist/mcp-server/tools/gitClone/registration.js +7 -4
  19. package/dist/mcp-server/tools/gitCommit/logic.js +98 -20
  20. package/dist/mcp-server/tools/gitCommit/registration.js +22 -15
  21. package/dist/mcp-server/tools/gitDiff/logic.js +9 -6
  22. package/dist/mcp-server/tools/gitDiff/registration.js +8 -5
  23. package/dist/mcp-server/tools/gitFetch/logic.js +10 -7
  24. package/dist/mcp-server/tools/gitFetch/registration.js +8 -5
  25. package/dist/mcp-server/tools/gitInit/index.js +2 -2
  26. package/dist/mcp-server/tools/gitInit/logic.js +9 -6
  27. package/dist/mcp-server/tools/gitInit/registration.js +66 -12
  28. package/dist/mcp-server/tools/gitLog/logic.js +53 -16
  29. package/dist/mcp-server/tools/gitLog/registration.js +8 -5
  30. package/dist/mcp-server/tools/gitMerge/logic.js +9 -6
  31. package/dist/mcp-server/tools/gitMerge/registration.js +8 -5
  32. package/dist/mcp-server/tools/gitPull/logic.js +11 -8
  33. package/dist/mcp-server/tools/gitPull/registration.js +7 -4
  34. package/dist/mcp-server/tools/gitPush/logic.js +12 -9
  35. package/dist/mcp-server/tools/gitPush/registration.js +7 -4
  36. package/dist/mcp-server/tools/gitRebase/logic.js +9 -6
  37. package/dist/mcp-server/tools/gitRebase/registration.js +8 -5
  38. package/dist/mcp-server/tools/gitRemote/logic.js +4 -5
  39. package/dist/mcp-server/tools/gitRemote/registration.js +2 -4
  40. package/dist/mcp-server/tools/gitReset/logic.js +5 -6
  41. package/dist/mcp-server/tools/gitReset/registration.js +2 -4
  42. package/dist/mcp-server/tools/gitSetWorkingDir/logic.js +5 -6
  43. package/dist/mcp-server/tools/gitSetWorkingDir/registration.js +22 -13
  44. package/dist/mcp-server/tools/gitShow/logic.js +5 -6
  45. package/dist/mcp-server/tools/gitShow/registration.js +3 -5
  46. package/dist/mcp-server/tools/gitStash/logic.js +5 -6
  47. package/dist/mcp-server/tools/gitStash/registration.js +3 -5
  48. package/dist/mcp-server/tools/gitStatus/logic.js +5 -6
  49. package/dist/mcp-server/tools/gitStatus/registration.js +2 -4
  50. package/dist/mcp-server/tools/gitTag/logic.js +3 -4
  51. package/dist/mcp-server/tools/gitTag/registration.js +2 -4
  52. package/dist/mcp-server/transports/authentication/authMiddleware.js +145 -0
  53. package/dist/mcp-server/transports/httpTransport.js +432 -0
  54. package/dist/mcp-server/transports/stdioTransport.js +87 -0
  55. package/dist/types-global/errors.js +2 -2
  56. package/dist/utils/index.js +12 -11
  57. package/dist/utils/{errorHandler.js → internal/errorHandler.js} +18 -8
  58. package/dist/utils/internal/index.js +3 -0
  59. package/dist/utils/internal/logger.js +254 -0
  60. package/dist/utils/{requestContext.js → internal/requestContext.js} +2 -3
  61. package/dist/utils/metrics/index.js +1 -0
  62. package/dist/utils/{tokenCounter.js → metrics/tokenCounter.js} +3 -3
  63. package/dist/utils/parsing/dateParser.js +62 -0
  64. package/dist/utils/parsing/index.js +2 -0
  65. package/dist/utils/{jsonParser.js → parsing/jsonParser.js} +3 -2
  66. package/dist/utils/{idGenerator.js → security/idGenerator.js} +4 -5
  67. package/dist/utils/security/index.js +3 -0
  68. package/dist/utils/{rateLimiter.js → security/rateLimiter.js} +7 -10
  69. package/dist/utils/{sanitization.js → security/sanitization.js} +4 -3
  70. package/package.json +12 -9
  71. package/dist/types-global/mcp.js +0 -59
  72. package/dist/types-global/tool.js +0 -1
  73. package/dist/utils/logger.js +0 -266
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Git MCP Server
2
2
 
3
3
  [![TypeScript](https://img.shields.io/badge/TypeScript-^5.8.3-blue.svg)](https://www.typescriptlang.org/)
4
- [![Model Context Protocol](https://img.shields.io/badge/MCP%20SDK-^1.10.2-green.svg)](https://modelcontextprotocol.io/)
5
- [![Version](https://img.shields.io/badge/Version-2.0.2-blue.svg)](./CHANGELOG.md)
4
+ [![Model Context Protocol](https://img.shields.io/badge/MCP%20SDK-^1.11.0-green.svg)](https://modelcontextprotocol.io/)
5
+ [![Version](https://img.shields.io/badge/Version-2.0.4-blue.svg)](./CHANGELOG.md)
6
6
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
7
7
  [![Status](https://img.shields.io/badge/Status-Stable-green.svg)](https://github.com/cyanheads/git-mcp-server/issues)
8
8
  [![GitHub](https://img.shields.io/github/stars/cyanheads/git-mcp-server?style=social)](https://github.com/cyanheads/git-mcp-server)
@@ -11,64 +11,13 @@ An MCP (Model Context Protocol) server providing tools to interact with Git repo
11
11
 
12
12
  Built on the [`cyanheads/mcp-ts-template`](https://github.com/cyanheads/mcp-ts-template), this server follows a modular architecture:
13
13
 
14
- > **Note:** This version (v2.0.0) focuses on refactoring and updating the core Git tools based on the latest MCP SDK. MCP Resource capabilities are not implemented in this version. For resource access, please use [v1.2.4](https://github.com/cyanheads/git-mcp-server/releases/tag/v1.2.4).
15
-
16
- ```mermaid
17
- flowchart TB
18
- subgraph API["API Layer"]
19
- direction LR
20
- MCP["MCP Protocol"]
21
- Val["Validation (Zod)"]
22
- San["Sanitization"]
23
-
24
- MCP --> Val --> San
25
- end
26
-
27
- subgraph Core["Core Components"]
28
- direction LR
29
- Config["Configuration"]
30
- Logger["Logging System"]
31
- Error["Error Handling"]
32
- Server["MCP Server (SDK)"]
33
-
34
- Config --> Server
35
- Logger --> Server
36
- Error --> Server
37
- end
38
-
39
- subgraph Implementation["Implementation Layer"]
40
- direction LR
41
- Tool["Tools (Git Logic)"]
42
- Util["Utilities"]
43
-
44
- Tool --> Server
45
- Util --> Tool
46
- end
47
-
48
- San --> Config
49
- San --> Server
50
-
51
- classDef layer fill:#2d3748,stroke:#4299e1,stroke-width:3px,rx:5,color:#fff
52
- classDef component fill:#1a202c,stroke:#a0aec0,stroke-width:2px,rx:3,color:#fff
53
- class API,Core,Implementation layer
54
- class MCP,Val,San,Config,Logger,Error,Server,Tool,Util component
55
- ```
56
-
57
- Implemented as an MCP server, it allows LLM agents and other compatible clients to interact with local Git repositories using standardized commands.
58
-
59
14
  > **Developer Note**: This repository includes a [.clinerules](.clinerules) file that serves as a developer cheat sheet for your LLM coding agent with quick reference for the codebase patterns, file locations, and code snippets.
60
15
 
61
16
  ## Table of Contents
62
17
 
63
- - [Overview](#overview)
64
- - [Features](#features)
65
- - [Installation](#installation)
66
- - [Configuration](#configuration)
67
- - [Project Structure](#project-structure)
68
- - [Tools](#tools)
69
- - [Resources](#resources)
70
- - [Development](#development)
71
- - [License](#license)
18
+ | [Overview](#overview) | [Features](#features) | [Installation](#installation) |
19
+ | [Configuration](#configuration) | [Project Structure](#project-structure) |
20
+ | [Tools](#tools) | [Resources](#resources) | [Development](#development) | [License](#license) |
72
21
 
73
22
  ## Overview
74
23
 
@@ -101,20 +50,27 @@ Leverages the robust utilities provided by the `mcp-ts-template`:
101
50
  ### Git Operations
102
51
 
103
52
  - **Direct Git CLI Execution**: Interacts with Git by securely executing the standard `git` command-line tool via Node.js `child_process`, ensuring full compatibility and access to Git's features.
104
-
105
53
  - **Comprehensive Command Coverage**: Exposes a wide range of Git commands as MCP tools (see [Tools](#tools) section).
106
54
  - **Repository Interaction**: Supports status checking, branching, staging, committing, fetching, pulling, pushing, diffing, logging, resetting, tagging, and more.
107
55
  - **Working Directory Management**: Allows setting and clearing a session-specific working directory for context persistence across multiple Git operations.
108
56
  - **Safety Features**: Includes checks and requires explicit confirmation for potentially destructive operations like `git clean` and `git reset --hard`.
57
+ - **Commit Signing**: Supports GPG or SSH signing for verified commits, controlled via the `GIT_SIGN_COMMITS` environment variable and server-side Git configuration. Includes an optional tool parameter to fall back to unsigned commits on signing failure.
109
58
 
110
59
  ## Installation
111
60
 
112
61
  ### Prerequisites
113
62
 
114
- - [Node.js (v18+)](https://nodejs.org/)
63
+ - [Node.js (>=18.0.0)](https://nodejs.org/)
115
64
  - [npm](https://www.npmjs.com/) (comes with Node.js)
116
65
  - [Git](https://git-scm.com/) installed and accessible in the system PATH.
117
66
 
67
+ ### Install via npm
68
+
69
+ 1. Install the package globally:
70
+ ```bash
71
+ npm install git-mcp-server
72
+ ```
73
+
118
74
  ### Install from Source
119
75
 
120
76
  1. Clone the repository:
@@ -128,9 +84,9 @@ Leverages the robust utilities provided by the `mcp-ts-template`:
128
84
  ```
129
85
  3. Build the project:
130
86
  ```bash
131
- npm run build
87
+ npm run build (or `npm run rebuild`)
132
88
  ```
133
- This compiles the TypeScript code to JavaScript in the `build/` directory and makes the entry point executable.
89
+ This compiles the TypeScript code to JavaScript in the `dist/` directory and makes the entry point executable.
134
90
 
135
91
  ## Configuration
136
92
 
@@ -138,20 +94,14 @@ Leverages the robust utilities provided by the `mcp-ts-template`:
138
94
 
139
95
  Configure the server using environment variables. Create a `.env` file in the project root (copy from `.env.example`) or set them in your environment.
140
96
 
141
- | Variable | Description | Default |
142
- | ---------------------- | ---------------------------------------------------------------------------------------- | ------------------- |
143
- | `MCP_TRANSPORT_TYPE` | Transport mechanism: `stdio` or `http`. | `stdio` |
144
- | `MCP_HTTP_PORT` | Port for the HTTP server (if `MCP_TRANSPORT_TYPE=http`). Retries next ports if busy. | `3000` |
145
- | `MCP_HTTP_HOST` | Host address for the HTTP server (if `MCP_TRANSPORT_TYPE=http`). | `127.0.0.1` |
146
- | `MCP_ALLOWED_ORIGINS` | Comma-separated list of allowed origins for CORS (if `MCP_TRANSPORT_TYPE=http`). | (none) |
147
- | `MCP_SERVER_NAME` | Name reported during MCP initialization. | `git-mcp-server` |
148
- | `MCP_SERVER_VERSION` | Version reported during MCP initialization. | (from package.json) |
149
- | `LOG_LEVEL` | Logging level (`debug`, `info`, `notice`, `warning`, `error`, `crit`, `alert`, `emerg`). | `info` |
150
- | `LOG_REDACT_PATTERNS` | Comma-separated regex patterns for redacting sensitive data in logs. | (predefined) |
151
- | `LOG_FILE_PATH` | Path for log file output. If unset, logs only to console. | (none) |
152
- | `LOG_MAX_FILE_SIZE_MB` | Max size (MB) for log file rotation. | `10` |
153
- | `LOG_MAX_FILES` | Max number of rotated log files to keep. | `5` |
154
- | `LOG_ZIP_ARCHIVES` | Compress rotated log files (`true`/`false`). | `true` |
97
+ | Variable | Description | Default |
98
+ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
99
+ | `MCP_TRANSPORT_TYPE` | Transport mechanism: `stdio` or `http`. | `stdio` |
100
+ | `MCP_HTTP_PORT` | Port for the HTTP server (if `MCP_TRANSPORT_TYPE=http`). Retries next ports if busy. | `3000` |
101
+ | `MCP_HTTP_HOST` | Host address for the HTTP server (if `MCP_TRANSPORT_TYPE=http`). | `127.0.0.1` |
102
+ | `MCP_ALLOWED_ORIGINS` | Comma-separated list of allowed origins for CORS (if `MCP_TRANSPORT_TYPE=http`). | (none) |
103
+ | `MCP_LOG_LEVEL` | Logging level (`debug`, `info`, `notice`, `warning`, `error`, `crit`, `alert`, `emerg`). Inherited from template. | `info` |
104
+ | `GIT_SIGN_COMMITS` | Set to `"true"` to enable signing attempts for commits made by the `git_commit` tool. Requires server-side Git/key setup (see below). | `false` |
155
105
 
156
106
  ### MCP Client Settings
157
107
 
@@ -160,12 +110,14 @@ Add to your MCP client settings (e.g., `cline_mcp_settings.json`):
160
110
  ```json
161
111
  {
162
112
  "mcpServers": {
163
- "git": {
113
+ "git-mcp-server": {
114
+ // Use a descriptive name
164
115
  "command": "node", // Use node to run the script
165
- "args": ["/path/to/your/git-mcp-server/build/index.js"], // Absolute path to the built entry point
116
+ "args": ["/path/to/your/git-mcp-server/dist/index.js"], // Absolute path to the built entry point
166
117
  "env": {
167
118
  // "MCP_TRANSPORT_TYPE": "http", // Optional: if using http
168
- // "MCP_HTTP_PORT": "3001" // Optional: if using http and non-default port
119
+ // "MCP_HTTP_PORT": "3010", // Optional: if using http and non-default port
120
+ // "GIT_SIGN_COMMITS": "true" // Optional: Enable commit signing attempts if server is configured
169
121
  },
170
122
  "disabled": false,
171
123
  "autoApprove": [] // Configure auto-approval rules if desired
@@ -184,7 +136,8 @@ src/
184
136
  ├── config/ # Configuration loading (env vars, package info)
185
137
  │ └── index.ts
186
138
  ├── mcp-server/ # Core MCP server logic and capability registration
187
- │ ├── server.ts # Server setup, transport handling, tool registration
139
+ │ ├── server.ts # Server setup, capability registration
140
+ │ ├── transports/ # Transport handling (stdio, http)
188
141
  │ ├── resources/ # MCP Resource implementations (currently none)
189
142
  │ └── tools/ # MCP Tool implementations (subdirs per tool)
190
143
  ├── types-global/ # Shared TypeScript type definitions
@@ -206,7 +159,7 @@ The Git MCP Server provides a suite of tools for interacting with Git repositori
206
159
  | `git_clean` | Removes untracked files. **Requires `force: true`**. | `path?`, `force`, `dryRun?`, `directories?`, `ignored?` |
207
160
  | `git_clear_working_dir` | Clears the session-specific working directory. | (none) |
208
161
  | `git_clone` | Clones a repository into a specified absolute path. | `repositoryUrl`, `targetPath`, `branch?`, `depth?`, `quiet?` |
209
- | `git_commit` | Commits staged changes with a message. | `path?`, `message`, `author?`, `allowEmpty?`, `amend?` |
162
+ | `git_commit` | Commits staged changes. Supports author override, signing control. | `path?`, `message`, `author?`, `allowEmpty?`, `amend?`, `forceUnsignedOnFailure?` |
210
163
  | `git_diff` | Shows changes between commits, working tree, etc. | `path?`, `commit1?`, `commit2?`, `staged?`, `file?` |
211
164
  | `git_fetch` | Downloads objects and refs from other repositories. | `path?`, `remote?`, `prune?`, `tags?`, `all?` |
212
165
  | `git_init` | Initializes a new Git repository at the specified absolute path. | `path`, `initialBranch?`, `bare?`, `quiet?` |
@@ -227,25 +180,24 @@ _Note: The `path` parameter for most tools defaults to the session's working dir
227
180
 
228
181
  ## Resources
229
182
 
230
- **MCP Resources are not implemented in this version (v2.0.0).**
183
+ **MCP Resources are not implemented in this version (v2.0.2).**
231
184
 
232
- This version focuses on the refactored Git tools implementation based on the latest `mcp-ts-template` and MCP SDK v1.10.2. Resource capabilities, previously available, have been temporarily removed during this major update.
185
+ This version focuses on the refactored Git tools implementation based on the latest `mcp-ts-template` and MCP SDK v1.11.0. Resource capabilities, previously available, have been temporarily removed during this major update.
233
186
 
234
187
  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)**.
235
188
 
236
189
  Future development may reintroduce resource capabilities in a subsequent release.
237
190
 
191
+ > **Note:** This version (v2.0.2) focuses on refactoring and updating the core Git tools based on the latest MCP SDK. MCP Resource capabilities are not implemented in this version. For resource access, please use [v1.2.4](https://github.com/cyanheads/git-mcp-server/releases/tag/v1.2.4).
192
+
238
193
  ## Development
239
194
 
240
195
  ### Build and Test
241
196
 
242
197
  ```bash
243
- # Build the project (compile TS to JS in build/ and make executable)
198
+ # Build the project (compile TS to JS in dist/ and make executable)
244
199
  npm run build
245
200
 
246
- # Watch for changes and recompile automatically
247
- npm run watch
248
-
249
201
  # Test the server locally using the MCP inspector tool (stdio transport)
250
202
  npm run inspector
251
203
 
@@ -257,6 +209,14 @@ npm run tree
257
209
 
258
210
  # Clean build artifacts and then rebuild the project
259
211
  npm run rebuild
212
+
213
+ # Start the server using stdio (default)
214
+ npm start
215
+ # Or explicitly:
216
+ npm run start:stdio
217
+
218
+ # Start the server using HTTP transport
219
+ npm run start:http
260
220
  ```
261
221
 
262
222
  ## License
@@ -2,14 +2,14 @@ import dotenv from "dotenv";
2
2
  import { readFileSync } from "fs";
3
3
  import { dirname, join } from "path";
4
4
  import { fileURLToPath } from "url";
5
- import { logger } from "../utils/logger.js"; // Import McpLogLevel and logger
5
+ // Removed logger import to break circular dependency
6
6
  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
10
  const pkgPath = join(__dirname, '../../package.json');
11
11
  // Default package information in case package.json is unreadable
12
- let pkg = { name: 'mcp-ts-template', version: '0.0.0' };
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
15
  pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
@@ -30,12 +30,24 @@ export const config = {
30
30
  logLevel: process.env.MCP_LOG_LEVEL || "info", // Use MCP_LOG_LEVEL consistently
31
31
  /** The runtime environment (e.g., "development", "production"). Defaults to "development". */
32
32
  environment: process.env.NODE_ENV || "development",
33
+ /** The communication transport type ('stdio' or 'http'). Defaults to 'stdio'. */
34
+ mcpTransportType: process.env.MCP_TRANSPORT_TYPE || "stdio",
35
+ /** Port for the HTTP transport. Defaults to 3000. */
36
+ mcpHttpPort: parseInt(process.env.MCP_HTTP_PORT || "3010", 10),
37
+ /** Host for the HTTP transport. Defaults to '127.0.0.1'. */
38
+ mcpHttpHost: process.env.MCP_HTTP_HOST || "127.0.0.1",
39
+ /** Allowed origins for HTTP transport (comma-separated). */
40
+ mcpAllowedOrigins: process.env.MCP_ALLOWED_ORIGINS?.split(',') || [],
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 === 'true',
33
43
  /** Security-related configurations. */
34
44
  security: {
35
45
  // Placeholder for security settings
36
46
  // Example: authRequired: process.env.AUTH_REQUIRED === 'true'
37
47
  /** Indicates if authentication is required for server operations. */
38
48
  authRequired: false,
49
+ /** Secret key for signing/verifying authentication tokens (required if authRequired is true). */
50
+ mcpAuthSecretKey: process.env.MCP_AUTH_SECRET_KEY || '', // Default to empty string, validation should happen elsewhere
39
51
  }
40
52
  // Note: mcpClient configuration is now loaded separately from mcp-config.json
41
53
  };
@@ -51,19 +63,5 @@ export const logLevel = config.logLevel;
51
63
  * @type {string}
52
64
  */
53
65
  export const environment = config.environment;
54
- // Define valid MCP log levels based on the logger's type definition
55
- const validMcpLogLevels = ['debug', 'info', 'notice', 'warning', 'error', 'crit', 'alert', 'emerg'];
56
- // Validate the configured log level
57
- let validatedMcpLogLevel = 'info'; // Default to 'info'
58
- if (validMcpLogLevels.includes(logLevel)) {
59
- validatedMcpLogLevel = logLevel;
60
- }
61
- else {
62
- // Silently default to 'info' if the configured level is invalid.
63
- // The logger initialization message will show the actual level being used.
64
- }
65
- // Initialize the logger with the validated MCP level AFTER config is defined.
66
- logger.initialize(validatedMcpLogLevel);
67
- // Log initialization message using the logger itself (will go to file and potentially MCP)
68
- logger.info(`Logger initialized. MCP logging level: ${validatedMcpLogLevel}`);
69
- logger.debug("Configuration loaded successfully", { config }); // Log loaded config at debug level
66
+ // Logger initialization is now handled in the main application entry point (e.g., src/index.ts)
67
+ // after the config module has been fully loaded.
package/dist/index.js CHANGED
@@ -1,15 +1,20 @@
1
1
  #!/usr/bin/env node
2
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; // Import McpServer type
3
- import { config, environment } from "./config/index.js";
4
- import { initializeAndStartServer } from "./mcp-server/server.js"; // Updated import
5
- import { logger } from "./utils/logger.js";
6
- // Import the service instance instead of the standalone function
7
- import { requestContextService } from "./utils/requestContext.js";
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import http from 'http'; // Import http module
4
+ import { config, environment, logLevel } from "./config/index.js"; // Import logLevel from config
5
+ import { initializeAndStartServer } from "./mcp-server/server.js";
6
+ // Import utils from barrel
7
+ import { logger, requestContextService } from './utils/index.js'; // Import McpLogLevel type
8
8
  /**
9
- * The main MCP server instance.
9
+ * The main MCP server instance (used for stdio transport).
10
10
  * @type {McpServer | undefined}
11
11
  */
12
- let server;
12
+ let mcpServerInstance;
13
+ /**
14
+ * The main HTTP server instance (used for http transport).
15
+ * @type {http.Server | undefined}
16
+ */
17
+ let httpServerInstance;
13
18
  /**
14
19
  * Gracefully shuts down the main MCP server.
15
20
  * Handles process termination signals (SIGTERM, SIGINT) and critical errors.
@@ -17,22 +22,50 @@ let server;
17
22
  * @param signal - The signal or event name that triggered the shutdown (e.g., "SIGTERM", "uncaughtException").
18
23
  */
19
24
  const shutdown = async (signal) => {
20
- // Define context for the shutdown operation
25
+ const transportType = (process.env.MCP_TRANSPORT_TYPE || 'stdio').toLowerCase();
21
26
  const shutdownContext = {
22
27
  operation: 'Shutdown',
23
28
  signal,
29
+ transport: transportType,
24
30
  };
25
31
  logger.info(`Received ${signal}. Starting graceful shutdown...`, shutdownContext);
26
32
  try {
27
- // Close the main MCP server
28
- if (server) {
29
- logger.info("Closing main MCP server...", shutdownContext);
30
- await server.close();
31
- logger.info("Main MCP server closed successfully", shutdownContext);
33
+ let closePromise = Promise.resolve();
34
+ if (transportType === 'stdio') {
35
+ // Close the main MCP server instance for stdio
36
+ if (mcpServerInstance) {
37
+ logger.info("Closing main MCP server (stdio)...", shutdownContext);
38
+ closePromise = mcpServerInstance.close();
39
+ }
40
+ else {
41
+ logger.warning("Stdio MCP server instance not found during shutdown.", shutdownContext);
42
+ }
32
43
  }
33
- else {
34
- logger.warning("Server instance not found during shutdown.", shutdownContext);
44
+ else if (transportType === 'http') {
45
+ // Close the main HTTP server listener for http
46
+ if (httpServerInstance) {
47
+ logger.info("Closing main HTTP server listener...", shutdownContext);
48
+ closePromise = new Promise((resolve, reject) => {
49
+ httpServerInstance.close((err) => {
50
+ if (err) {
51
+ logger.error("Error closing HTTP server listener", { ...shutdownContext, error: err.message });
52
+ reject(err);
53
+ }
54
+ else {
55
+ logger.info("Main HTTP server listener closed successfully", shutdownContext);
56
+ resolve();
57
+ }
58
+ });
59
+ });
60
+ }
61
+ else {
62
+ logger.warning("HTTP server instance not found during shutdown.", shutdownContext);
63
+ }
64
+ // Note: Individual session transports (StreamableHTTPServerTransport) are closed
65
+ // when the client disconnects or sends a DELETE request, managed in httpTransport.ts.
35
66
  }
67
+ // Wait for the appropriate server/listener to close
68
+ await closePromise;
36
69
  logger.info("Graceful shutdown completed successfully", shutdownContext);
37
70
  process.exit(0);
38
71
  }
@@ -52,7 +85,21 @@ const shutdown = async (signal) => {
52
85
  * and registers signal handlers for graceful shutdown and error handling.
53
86
  */
54
87
  const start = async () => {
55
- // Create application-level request context using the service instance
88
+ // --- Initialize Logger FIRST ---
89
+ // Define valid MCP log levels based on the logger's type definition
90
+ const validMcpLogLevels = ['debug', 'info', 'notice', 'warning', 'error', 'crit', 'alert', 'emerg'];
91
+ let validatedMcpLogLevel = 'info'; // Default to 'info'
92
+ if (validMcpLogLevels.includes(logLevel)) {
93
+ validatedMcpLogLevel = logLevel;
94
+ }
95
+ else {
96
+ // Use console.warn as logger isn't ready yet
97
+ console.warn(`Invalid MCP_LOG_LEVEL "${logLevel}" found in config. Defaulting to "info".`);
98
+ }
99
+ // Initialize the logger singleton instance with the validated level.
100
+ logger.initialize(validatedMcpLogLevel);
101
+ // Now it's safe to use the logger.
102
+ // --- Start Application ---
56
103
  const transportType = (process.env.MCP_TRANSPORT_TYPE || 'stdio').toLowerCase();
57
104
  const startupContext = requestContextService.createRequestContext({
58
105
  operation: `ServerStartup_${transportType}`, // Include transport in operation name
@@ -64,22 +111,25 @@ const start = async () => {
64
111
  try {
65
112
  // Initialize the server instance and start the selected transport
66
113
  logger.debug("Initializing and starting MCP server transport", startupContext);
67
- // Start the server transport. For stdio, this returns the server instance.
68
- // For http, it sets up the listener and returns void (or potentially the http.Server).
69
- // We only need to store the instance for stdio shutdown.
70
- const potentialServerInstance = await initializeAndStartServer();
71
- if (transportType === 'stdio' && potentialServerInstance instanceof McpServer) {
72
- server = potentialServerInstance; // Store only for stdio
114
+ // Start the server transport. This returns the McpServer instance for stdio
115
+ // or the http.Server instance for http.
116
+ const serverOrHttpInstance = await initializeAndStartServer();
117
+ if (transportType === 'stdio' && serverOrHttpInstance instanceof McpServer) {
118
+ mcpServerInstance = serverOrHttpInstance; // Store McpServer for stdio shutdown
119
+ logger.debug("Stored McpServer instance for stdio transport.", startupContext);
120
+ }
121
+ else if (transportType === 'http' && serverOrHttpInstance instanceof http.Server) {
122
+ httpServerInstance = serverOrHttpInstance; // Store http.Server for http shutdown
123
+ logger.debug("Stored http.Server instance for http transport.", startupContext);
73
124
  }
74
125
  else {
75
- // For HTTP, server instances are managed per-session in server.ts
76
- // The main http server listener keeps the process alive.
77
- // Shutdown for HTTP needs to handle closing the main http server.
78
- // We might need to return the httpServer from initializeAndStartServer if
79
- // we want to close it explicitly here during shutdown.
80
- // For now, we don't store anything globally for HTTP transport.
126
+ // This case should ideally not happen if initializeAndStartServer works correctly
127
+ logger.warning("initializeAndStartServer did not return the expected instance type.", {
128
+ ...startupContext,
129
+ instanceType: typeof serverOrHttpInstance
130
+ });
81
131
  }
82
- // If initializeAndStartServer failed, it would have thrown an error,
132
+ // If initializeAndStartServer failed internally, it would have thrown an error,
83
133
  // and execution would jump to the outer catch block.
84
134
  logger.info(`${config.mcpServerName} is running with ${transportType} transport`, {
85
135
  ...startupContext,