@aashari/boilerplate-mcp-server 1.13.4 → 1.14.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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [1.14.0](https://github.com/aashari/boilerplate-mcp-server/compare/v1.13.5...v1.14.0) (2025-09-09)
2
+
3
+
4
+ ### Features
5
+
6
+ * modernize dependencies and enhance testing infrastructure ([#67](https://github.com/aashari/boilerplate-mcp-server/issues/67)) ([a74f114](https://github.com/aashari/boilerplate-mcp-server/commit/a74f1145b7e80615a9a0c907b9d19eb5e4fbd2e8))
7
+
8
+ ## [1.13.5](https://github.com/aashari/boilerplate-mcp-server/compare/v1.13.4...v1.13.5) (2025-08-02)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * allow Gemini to run even if build fails to catch PR issues ([c7b31b3](https://github.com/aashari/boilerplate-mcp-server/commit/c7b31b33674b4ef458d6d201aa22673f13a5247a))
14
+
1
15
  ## [1.13.4](https://github.com/aashari/boilerplate-mcp-server/compare/v1.13.3...v1.13.4) (2025-08-02)
2
16
 
3
17
 
package/README.md CHANGED
@@ -1,20 +1,19 @@
1
1
  # Boilerplate MCP Server
2
2
 
3
- A foundation for developing custom Model Context Protocol (MCP) servers in TypeScript. Provides a complete layered architecture pattern, working example tools, and developer infrastructure to connect AI assistants with external APIs and data sources.
3
+ A production-ready foundation for developing custom Model Context Protocol (MCP) servers in TypeScript. Provides a complete layered architecture pattern, working example implementation, and comprehensive developer infrastructure to connect AI assistants with external APIs and data sources.
4
4
 
5
5
  [![NPM Version](https://img.shields.io/npm/v/@aashari/boilerplate-mcp-server)](https://www.npmjs.com/package/@aashari/boilerplate-mcp-server)
6
- [![Build Status](https://img.shields.io/github/workflow/status/aashari/boilerplate-mcp-server/CI)](https://github.com/aashari/boilerplate-mcp-server/actions)
7
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.0%2B-blue)](https://www.typescriptlang.org/)
8
6
  [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
9
7
 
10
8
  ## Features
11
9
 
12
- - **Multiple Transport Support**: STDIO and Streamable HTTP transports
13
- - **Production-Ready Architecture**: Clean separation between CLI, tools, controllers, and services
14
- - **Type Safety**: Built with TypeScript for improved developer experience
15
- - **Working Example**: Fully implemented IP address lookup tools
16
- - **Testing Framework**: Ready-to-use testing infrastructure with coverage reporting
17
- - **Complete Developer Tooling**: Pre-configured ESLint, Prettier, TypeScript
10
+ - **Dual Transport Support**: STDIO and Streamable HTTP transports with automatic fallback
11
+ - **5-Layer Architecture**: Clean separation between CLI, tools, controllers, services, and utilities
12
+ - **Type Safety**: Full TypeScript implementation with Zod schema validation
13
+ - **Complete IP Address Example**: Tools, resources, and CLI commands for IP geolocation
14
+ - **Comprehensive Testing**: Unit and integration tests with coverage reporting
15
+ - **Production Tooling**: ESLint, Prettier, semantic-release, and MCP Inspector integration
16
+ - **Error Handling**: Structured error handling with contextual logging
18
17
 
19
18
  ## What is MCP?
20
19
 
@@ -35,35 +34,40 @@ cd boilerplate-mcp-server
35
34
  # Install dependencies
36
35
  npm install
37
36
 
37
+ # Build the project
38
+ npm run build
39
+
38
40
  # Run in different modes:
39
41
 
40
42
  # 1. CLI Mode - Execute commands directly
41
43
  npm run cli -- get-ip-details 8.8.8.8
44
+ npm run cli -- get-ip-details # Get your current IP
45
+ npm run cli -- get-ip-details 1.1.1.1 --include-extended-data
42
46
 
43
- # 2. STDIO Transport - For direct AI assistant integration
47
+ # 2. STDIO Transport - For AI assistant integration (Claude Desktop, Cursor)
44
48
  npm run mcp:stdio
45
49
 
46
- # 3. HTTP Transport - For web-based integrations (default)
50
+ # 3. HTTP Transport - For web-based integrations
47
51
  npm run mcp:http
48
52
 
49
53
  # 4. Development with MCP Inspector
50
- npm run mcp:inspect
54
+ npm run mcp:inspect # Auto-opens browser with debugging UI
51
55
  ```
52
56
 
53
57
  ## Transport Modes
54
58
 
55
59
  ### STDIO Transport
56
- - Traditional subprocess communication via stdin/stdout
57
- - Ideal for local AI assistant integrations
58
- - Run with: `TRANSPORT_MODE=stdio npm run build && node dist/index.js`
59
-
60
- ### Streamable HTTP Transport (Default)
61
- - Modern HTTP-based transport with Server-Sent Events (SSE)
62
- - Supports multiple concurrent connections
63
- - Runs on port 3000 by default (configurable via PORT env var)
64
- - Endpoint: `http://localhost:3000/mcp`
65
- - Health check: `http://localhost:3000/`
66
- - Run with: `TRANSPORT_MODE=http npm run build && node dist/index.js`
60
+ - JSON-RPC communication via stdin/stdout
61
+ - Used by Claude Desktop, Cursor AI, and other local AI assistants
62
+ - Run with: `TRANSPORT_MODE=stdio node dist/index.js`
63
+
64
+ ### Streamable HTTP Transport
65
+ - HTTP-based transport with Server-Sent Events (SSE)
66
+ - Supports multiple concurrent connections and web integrations
67
+ - Runs on port 3000 by default (configurable via `PORT` env var)
68
+ - MCP Endpoint: `http://localhost:3000/mcp`
69
+ - Health Check: `http://localhost:3000/` → Returns server version
70
+ - Run with: `TRANSPORT_MODE=http node dist/index.js`
67
71
 
68
72
  ## Architecture Overview
69
73
 
@@ -72,96 +76,138 @@ npm run mcp:inspect
72
76
 
73
77
  ```
74
78
  src/
75
- ├── cli/ # Command-line interfaces
76
- │ ├── index.ts # CLI entry point
77
- │ └── *.cli.ts # Feature-specific CLI modules
78
- ├── controllers/ # Business logic
79
- └── *.controller.ts # Feature controllers
80
- ├── services/ # External API interactions
81
- │ └── *.service.ts # Service modules
82
- ├── tools/ # MCP tool definitions
83
- ├── *.tool.ts # Tool implementations
84
- │ └── *.types.ts # Tool argument schemas
85
- ├── resources/ # MCP resource definitions
86
- │ └── *.resource.ts # Resource implementations
87
- ├── types/ # Type definitions
88
- │ └── common.types.ts # Shared type definitions
89
- ├── utils/ # Shared utilities
90
- ├── logger.util.ts # Structured logging
91
- ├── error.util.ts # Error handling
92
- └── ... # Other utility modules
93
- └── index.ts # Server entry point
79
+ ├── cli/ # Command-line interfaces
80
+ │ ├── index.ts # CLI entry point with Commander setup
81
+ │ └── ipaddress.cli.ts # IP address CLI commands
82
+ ├── controllers/ # Business logic orchestration
83
+ ├── ipaddress.controller.ts # IP lookup business logic
84
+ │ └── ipaddress.formatter.ts # Response formatting
85
+ ├── services/ # External API interactions
86
+ ├── vendor.ip-api.com.service.ts # ip-api.com service
87
+ └── vendor.ip-api.com.types.ts # Service type definitions
88
+ ├── tools/ # MCP tool definitions (AI interface)
89
+ ├── ipaddress.tool.ts # IP lookup tool for AI assistants
90
+ │ └── ipaddress.types.ts # Tool argument schemas
91
+ ├── resources/ # MCP resource definitions
92
+ │ └── ipaddress.resource.ts # IP lookup resource (URI: ip://address)
93
+ ├── types/ # Global type definitions
94
+ └── common.types.ts # Shared interfaces (ControllerResponse, etc.)
95
+ ├── utils/ # Shared utilities
96
+ ├── logger.util.ts # Contextual logging system
97
+ │ ├── error.util.ts # MCP-specific error formatting
98
+ │ ├── error-handler.util.ts # Error handling utilities
99
+ │ ├── config.util.ts # Environment configuration
100
+ │ ├── constants.util.ts # Version and package constants
101
+ │ ├── formatter.util.ts # Markdown formatting
102
+ │ └── transport.util.ts # HTTP transport utilities
103
+ └── index.ts # Server entry point (dual transport)
94
104
  ```
95
105
 
96
106
  </details>
97
107
 
98
- ## Layered Architecture
108
+ ## 5-Layer Architecture
99
109
 
100
110
  The boilerplate follows a clean, layered architecture that promotes maintainability and clear separation of concerns:
101
111
 
102
- ### 1. CLI Layer (`src/cli/*.cli.ts`)
112
+ ### 1. CLI Layer (`src/cli/`)
113
+
114
+ - **Purpose**: Command-line interfaces for direct tool usage and testing
115
+ - **Implementation**: Commander-based argument parsing with contextual error handling
116
+ - **Example**: `get-ip-details [ipAddress] --include-extended-data --no-use-https`
117
+ - **Pattern**: Register commands → Parse arguments → Call controllers → Handle errors
118
+
119
+ ### 2. Tools Layer (`src/tools/`)
103
120
 
104
- - **Purpose**: Command-line interfaces that parse arguments and call controllers
105
- - **Pattern**: Use `commander` for argument parsing, call controllers, handle errors with `handleCliError`
106
- - **Naming**: `<feature>.cli.ts`
121
+ - **Purpose**: MCP tool definitions that AI assistants can invoke
122
+ - **Implementation**: Zod schema validation with structured responses
123
+ - **Example**: `ip_get_details` tool with optional IP address and configuration options
124
+ - **Pattern**: Define schema → Validate args → Call controller → Format MCP response
107
125
 
108
- ### 2. Tools Layer (`src/tools/*.tool.ts`)
126
+ ### 3. Resources Layer (`src/resources/`)
109
127
 
110
- - **Purpose**: MCP tool definitions exposed to AI assistants
111
- - **Pattern**: Use `zod` for schema validation, call controllers, format responses for MCP
112
- - **Naming**: `<feature>.tool.ts` with types in `<feature>.types.ts`
128
+ - **Purpose**: MCP resources providing contextual data accessible via URIs
129
+ - **Implementation**: Resource handlers that respond to URI-based requests
130
+ - **Example**: `ip://8.8.8.8` resource providing IP geolocation data
131
+ - **Pattern**: Register URI patterns → Parse requests → Return formatted content
113
132
 
114
- ### 3. Controllers Layer (`src/controllers/*.controller.ts`)
133
+ ### 4. Controllers Layer (`src/controllers/`)
115
134
 
116
- - **Purpose**: Business logic orchestration, error handling, response formatting
117
- - **Pattern**: Return standardized `ControllerResponse` objects, throw errors with context
118
- - **Naming**: `<feature>.controller.ts` with optional `<feature>.formatter.ts`
135
+ - **Purpose**: Business logic orchestration with comprehensive error handling
136
+ - **Implementation**: Options validation, fallback logic, response formatting
137
+ - **Example**: IP lookup with HTTPS fallback, test environment detection, API token validation
138
+ - **Pattern**: Validate inputs → Apply defaults → Call services → Format responses
119
139
 
120
- ### 4. Services Layer (`src/services/*.service.ts`)
140
+ ### 5. Services Layer (`src/services/`)
121
141
 
122
- - **Purpose**: External API interactions and data handling
123
- - **Pattern**: Pure API calls with minimal logic, return raw data
124
- - **Naming**: `<feature>.service.ts` or `vendor.<vendor>.<feature>.service.ts`
142
+ - **Purpose**: Direct external API interactions with minimal business logic
143
+ - **Implementation**: HTTP transport utilities with structured error handling
144
+ - **Example**: ip-api.com API calls with authentication and field selection
145
+ - **Pattern**: Build requests → Make API calls → Validate responses → Return raw data
125
146
 
126
- ### 5. Utils Layer (`src/utils/*.util.ts`)
147
+ ### 6. Utils Layer (`src/utils/`)
127
148
 
128
- - **Purpose**: Shared functionality across the application
129
- - **Key Utils**: Logging, error handling, formatting, configuration
149
+ - **Purpose**: Shared functionality across all layers
150
+ - **Key Components**:
151
+ - `logger.util.ts`: Contextual logging (file:method context)
152
+ - `error.util.ts`: MCP-specific error formatting
153
+ - `transport.util.ts`: HTTP/API utilities with retry logic
154
+ - `config.util.ts`: Environment configuration management
130
155
 
131
156
  ## Developer Guide
132
157
 
133
158
  ### Development Scripts
134
159
 
135
160
  ```bash
136
- # Development
137
- npm run build # Build TypeScript
138
- npm run clean # Clean build artifacts
161
+ # Build and Clean
162
+ npm run build # Build TypeScript to dist/
163
+ npm run clean # Remove dist/ and coverage/
164
+ npm run prepare # Build + ensure executable permissions (for npm publish)
165
+
166
+ # CLI Testing
167
+ npm run cli -- get-ip-details 8.8.8.8 # Test specific IP
168
+ npm run cli -- get-ip-details --include-extended-data # Test with extended data
169
+ npm run cli -- get-ip-details --no-use-https # Test with HTTP
139
170
 
140
- # Running different modes
141
- npm run cli -- [command] # Run CLI commands
142
- npm run mcp:stdio # Run with STDIO transport
143
- npm run mcp:http # Run with HTTP transport (default)
144
- npm run mcp:inspect # Run with MCP Inspector
171
+ # MCP Server Modes
172
+ npm run mcp:stdio # STDIO transport for AI assistants
173
+ npm run mcp:http # HTTP transport on port 3000
174
+ npm run mcp:inspect # HTTP + auto-open MCP Inspector
145
175
 
146
- # Development modes
147
- npm run dev:stdio # STDIO with inspector
148
- npm run dev:http # HTTP in development mode
176
+ # Development with Debugging
177
+ npm run dev:stdio # STDIO with MCP Inspector integration
178
+ npm run dev:http # HTTP with debug logging enabled
149
179
 
150
180
  # Testing
151
- npm test # Run all tests
181
+ npm test # Run all tests (Jest)
152
182
  npm run test:coverage # Generate coverage report
183
+ npm run test:cli # Run CLI-specific tests
153
184
 
154
185
  # Code Quality
155
- npm run lint # Run ESLint
156
- npm run format # Format with Prettier
186
+ npm run lint # ESLint with TypeScript rules
187
+ npm run format # Prettier formatting
188
+ npm run update:deps # Update dependencies
157
189
  ```
158
190
 
159
191
  ### Environment Variables
160
192
 
161
- - `TRANSPORT_MODE`: Set to `stdio` or `http` (default: `http`)
193
+ #### Core Configuration
194
+ - `TRANSPORT_MODE`: Transport mode (`stdio` | `http`, default: `stdio`)
162
195
  - `PORT`: HTTP server port (default: `3000`)
163
- - `DEBUG`: Enable debug logging (default: `false`)
164
- - `IPAPI_API_TOKEN`: API token for ip-api.com (optional)
196
+ - `DEBUG`: Enable debug logging (`true` | `false`, default: `false`)
197
+
198
+ #### IP API Configuration
199
+ - `IPAPI_API_TOKEN`: API token for ip-api.com extended data (optional, free tier available)
200
+
201
+ #### Example `.env` File
202
+ ```bash
203
+ # Basic configuration
204
+ TRANSPORT_MODE=http
205
+ PORT=3001
206
+ DEBUG=true
207
+
208
+ # Extended data (requires ip-api.com account)
209
+ IPAPI_API_TOKEN=your_token_here
210
+ ```
165
211
 
166
212
  ### Debugging Tools
167
213
 
@@ -198,63 +244,110 @@ Create `~/.mcp/configs.json`:
198
244
 
199
245
  ### 1. Define Service Layer
200
246
 
201
- Create a new service in `src/services/` to interact with your external API:
247
+ Create a new service in `src/services/` following the vendor-specific naming pattern:
202
248
 
203
249
  ```typescript
204
- // src/services/example.service.ts
250
+ // src/services/vendor.example-api.service.ts
205
251
  import { Logger } from '../utils/logger.util.js';
252
+ import { fetchApi } from '../utils/transport.util.js';
253
+ import { ExampleApiResponse, ExampleApiRequestOptions } from './vendor.example-api.types.js';
254
+ import { createApiError, McpError } from '../utils/error.util.js';
255
+
256
+ const serviceLogger = Logger.forContext('services/vendor.example-api.service.ts');
206
257
 
207
- const logger = Logger.forContext('services/example.service.ts');
258
+ async function get(
259
+ param?: string,
260
+ options: ExampleApiRequestOptions = {}
261
+ ): Promise<ExampleApiResponse> {
262
+ const methodLogger = serviceLogger.forMethod('get');
263
+ methodLogger.debug(`Calling Example API with param: ${param}`);
208
264
 
209
- export async function getData(param: string): Promise<any> {
210
- logger.debug('Getting data', { param });
211
- // API interaction code here
212
- return { result: 'example data' };
265
+ try {
266
+ const url = `https://api.example.com/${param || 'default'}`;
267
+ const rawData = await fetchApi<ExampleApiResponse>(url, {
268
+ headers: options.apiKey ? { 'Authorization': `Bearer ${options.apiKey}` } : {}
269
+ });
270
+
271
+ methodLogger.debug('Received successful response from Example API');
272
+ return rawData;
273
+ } catch (error) {
274
+ methodLogger.error('Service error fetching data', error);
275
+
276
+ if (error instanceof McpError) {
277
+ throw error;
278
+ }
279
+
280
+ throw createApiError(
281
+ 'Unexpected service error while fetching data',
282
+ undefined,
283
+ error
284
+ );
285
+ }
213
286
  }
287
+
288
+ export default { get };
214
289
  ```
215
290
 
216
291
  ### 2. Create Controller
217
292
 
218
- Add a controller in `src/controllers/` to handle business logic:
293
+ Add a controller in `src/controllers/` to handle business logic with error context:
219
294
 
220
295
  ```typescript
221
296
  // src/controllers/example.controller.ts
222
297
  import { Logger } from '../utils/logger.util.js';
223
- import * as exampleService from '../services/example.service.js';
224
- import { formatMarkdown } from '../utils/formatter.util.js';
225
- import { handleControllerError } from '../utils/error-handler.util.js';
298
+ import exampleService from '../services/vendor.example-api.service.js';
299
+ import { formatExample } from './example.formatter.js';
300
+ import { handleControllerError, buildErrorContext } from '../utils/error-handler.util.js';
226
301
  import { ControllerResponse } from '../types/common.types.js';
302
+ import { config } from '../utils/config.util.js';
227
303
 
228
304
  const logger = Logger.forContext('controllers/example.controller.ts');
229
305
 
230
306
  export interface GetDataOptions {
231
307
  param?: string;
308
+ includeMetadata?: boolean;
232
309
  }
233
310
 
234
- export async function getData(
235
- options: GetDataOptions = {},
311
+ async function getData(
312
+ options: GetDataOptions = {}
236
313
  ): Promise<ControllerResponse> {
237
- try {
238
- logger.debug('Getting data with options', options);
239
-
240
- const data = await exampleService.getData(options.param || 'default');
314
+ const methodLogger = logger.forMethod('getData');
315
+ methodLogger.debug(`Getting data for param: ${options.param || 'default'}`, options);
241
316
 
242
- const content = formatMarkdown(data);
243
-
244
- return { content };
245
- } catch (error) {
246
- throw handleControllerError(error, {
247
- entityType: 'ExampleData',
248
- operation: 'getData',
249
- source: 'controllers/example.controller.ts',
317
+ try {
318
+ // Apply business logic and defaults
319
+ const apiKey = config.get('EXAMPLE_API_TOKEN');
320
+
321
+ // Call service layer
322
+ const data = await exampleService.get(options.param, {
323
+ apiKey,
324
+ includeMetadata: options.includeMetadata ?? false
250
325
  });
326
+
327
+ // Format response
328
+ const formattedContent = formatExample(data);
329
+ return { content: formattedContent };
330
+
331
+ } catch (error) {
332
+ throw handleControllerError(
333
+ error,
334
+ buildErrorContext(
335
+ 'ExampleData',
336
+ 'getData',
337
+ 'controllers/example.controller.ts@getData',
338
+ options.param || 'default',
339
+ { options }
340
+ )
341
+ );
251
342
  }
252
343
  }
344
+
345
+ export default { getData };
253
346
  ```
254
347
 
255
348
  ### 3. Implement MCP Tool
256
349
 
257
- Create a tool definition in `src/tools/`:
350
+ Create a tool definition in `src/tools/` following the registration pattern:
258
351
 
259
352
  ```typescript
260
353
  // src/tools/example.tool.ts
@@ -262,74 +355,109 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
262
355
  import { z } from 'zod';
263
356
  import { Logger } from '../utils/logger.util.js';
264
357
  import { formatErrorForMcpTool } from '../utils/error.util.js';
265
- import * as exampleController from '../controllers/example.controller.js';
358
+ import exampleController from '../controllers/example.controller.js';
266
359
 
267
360
  const logger = Logger.forContext('tools/example.tool.ts');
268
361
 
269
- const GetDataArgs = z.object({
270
- param: z.string().optional().describe('Optional parameter'),
362
+ // Define Zod schema for tool arguments
363
+ const GetDataSchema = z.object({
364
+ param: z.string().optional().describe('Optional parameter for the API call'),
365
+ includeMetadata: z.boolean().optional().default(false)
366
+ .describe('Whether to include additional metadata in the response')
271
367
  });
272
368
 
273
- type GetDataArgsType = z.infer<typeof GetDataArgs>;
274
-
275
- async function handleGetData(args: GetDataArgsType) {
369
+ async function handleGetData(args: Record<string, unknown>) {
370
+ const methodLogger = logger.forMethod('handleGetData');
371
+
276
372
  try {
277
- logger.debug('Tool get_data called', args);
373
+ methodLogger.debug('Tool example_get_data called', args);
278
374
 
375
+ // Validate arguments with Zod
376
+ const validatedArgs = GetDataSchema.parse(args);
377
+
378
+ // Call controller
279
379
  const result = await exampleController.getData({
280
- param: args.param,
380
+ param: validatedArgs.param,
381
+ includeMetadata: validatedArgs.includeMetadata
281
382
  });
282
383
 
384
+ // Return MCP-formatted response
283
385
  return {
284
- content: [{ type: 'text' as const, text: result.content }],
386
+ content: [
387
+ {
388
+ type: 'text' as const,
389
+ text: result.content
390
+ }
391
+ ]
285
392
  };
286
393
  } catch (error) {
287
- logger.error('Tool get_data failed', error);
394
+ methodLogger.error('Tool example_get_data failed', error);
288
395
  return formatErrorForMcpTool(error);
289
396
  }
290
397
  }
291
398
 
292
- export function register(server: McpServer) {
399
+ // Registration function following the pattern used by existing tools
400
+ function registerTools(server: McpServer) {
401
+ const registerLogger = logger.forMethod('registerTools');
402
+ registerLogger.debug('Registering example tools...');
403
+
293
404
  server.tool(
294
- 'get_data',
295
- `Gets data from the example API, optionally using \`param\`.
296
- Use this to fetch example data. Returns formatted data as Markdown.`,
297
- GetDataArgs.shape,
298
- handleGetData,
405
+ 'example_get_data',
406
+ `Gets data from the Example API with optional parameter.
407
+ Use this tool to fetch example data. Returns formatted data as Markdown.`,
408
+ GetDataSchema.shape,
409
+ handleGetData
299
410
  );
411
+
412
+ registerLogger.debug('Example tools registered successfully');
300
413
  }
414
+
415
+ export default { registerTools };
301
416
  ```
302
417
 
303
418
  ### 4. Add CLI Support
304
419
 
305
- Create a CLI command in `src/cli/`:
420
+ Create a CLI command in `src/cli/` following the Commander pattern:
306
421
 
307
422
  ```typescript
308
423
  // src/cli/example.cli.ts
309
- import { program } from 'commander';
424
+ import { Command } from 'commander';
310
425
  import { Logger } from '../utils/logger.util.js';
311
- import * as exampleController from '../controllers/example.controller.js';
312
- import { handleCliError } from '../utils/error-handler.util.js';
426
+ import exampleController from '../controllers/example.controller.js';
427
+ import { handleCliError } from '../utils/error.util.js';
313
428
 
314
429
  const logger = Logger.forContext('cli/example.cli.ts');
315
430
 
316
- program
317
- .command('get-data')
318
- .description('Get example data')
319
- .option('--param <value>', 'Optional parameter')
320
- .action(async (options) => {
321
- try {
322
- logger.debug('CLI get-data called', options);
323
-
324
- const result = await exampleController.getData({
325
- param: options.param,
326
- });
327
-
328
- console.log(result.content);
329
- } catch (error) {
330
- handleCliError(error);
331
- }
332
- });
431
+ function register(program: Command) {
432
+ const methodLogger = logger.forMethod('register');
433
+ methodLogger.debug('Registering example CLI commands...');
434
+
435
+ program
436
+ .command('get-data')
437
+ .description('Gets data from the Example API')
438
+ .argument('[param]', 'Optional parameter for the API call')
439
+ .option('-m, --include-metadata', 'Include additional metadata in response')
440
+ .action(async (param, options) => {
441
+ const actionLogger = logger.forMethod('action:get-data');
442
+
443
+ try {
444
+ actionLogger.debug('CLI get-data called', { param, options });
445
+
446
+ const result = await exampleController.getData({
447
+ param,
448
+ includeMetadata: options.includeMetadata || false
449
+ });
450
+
451
+ console.log(result.content);
452
+ } catch (error) {
453
+ handleCliError(error);
454
+ }
455
+ });
456
+
457
+ methodLogger.debug('Example CLI commands registered successfully');
458
+ }
459
+
460
+ export default { register };
333
461
  ```
334
462
 
335
463
  ### 5. Register Components
@@ -337,48 +465,142 @@ program
337
465
  Update the entry points to register your new components:
338
466
 
339
467
  ```typescript
340
- // In src/cli/index.ts
341
- import '../cli/example.cli.js';
468
+ // 1. Register CLI in src/cli/index.ts
469
+ import exampleCli from './example.cli.js';
470
+
471
+ export async function runCli(args: string[]) {
472
+ // ... existing setup code ...
473
+
474
+ // Register CLI commands
475
+ exampleCli.register(program); // Add this line
476
+
477
+ // ... rest of function
478
+ }
479
+
480
+ // 2. Register Tools in src/index.ts
481
+ import exampleTools from './tools/example.tool.js';
342
482
 
343
- // In src/index.ts (for the tool)
344
- import exampleTool from './tools/example.tool.js';
345
- // Then in registerTools function:
346
- exampleTool.register(server);
483
+ // In the startServer function, after existing registrations:
484
+ exampleTools.registerTools(serverInstance);
347
485
  ```
348
486
 
349
487
  </details>
350
488
 
489
+ ## IP Address Example Implementation
490
+
491
+ The boilerplate includes a complete IP address geolocation example demonstrating all layers:
492
+
493
+ ### Available Tools & Commands
494
+
495
+ **CLI Commands:**
496
+ ```bash
497
+ npm run cli -- get-ip-details # Get current public IP
498
+ npm run cli -- get-ip-details 8.8.8.8 # Get details for specific IP
499
+ npm run cli -- get-ip-details 1.1.1.1 --include-extended-data # With extended data
500
+ npm run cli -- get-ip-details 8.8.8.8 --no-use-https # Force HTTP (for free tier)
501
+ ```
502
+
503
+ **MCP Tools:**
504
+ - `ip_get_details` - IP geolocation lookup for AI assistants
505
+
506
+ **MCP Resources:**
507
+ - `ip://` - Current IP details
508
+ - `ip://8.8.8.8` - Specific IP details
509
+
510
+ ### Features Demonstrated
511
+
512
+ - **Fallback Logic**: HTTPS → HTTP fallback for free tier users
513
+ - **Environment Detection**: Different behavior in test vs production
514
+ - **API Token Support**: Optional token for extended data (ASN, mobile detection, etc.)
515
+ - **Error Handling**: Structured errors for private/reserved IP addresses
516
+ - **Response Formatting**: Clean Markdown output with geolocation data
517
+
518
+ ### Configuration Options
519
+
520
+ ```bash
521
+ # Optional - for extended data features
522
+ IPAPI_API_TOKEN=your_token_from_ip-api.com
523
+
524
+ # Development
525
+ DEBUG=true # Enable detailed logging
526
+ TRANSPORT_MODE=http # Use HTTP transport
527
+ PORT=3001 # Custom port
528
+ ```
529
+
351
530
  ## Publishing Your MCP Server
352
531
 
353
- 1. Update package.json with your details:
532
+ 1. **Customize Package Details:**
354
533
  ```json
355
534
  {
356
535
  "name": "your-mcp-server-name",
357
- "version": "1.0.0",
536
+ "version": "1.0.0",
358
537
  "description": "Your custom MCP server",
359
538
  "author": "Your Name",
360
- // Other fields...
539
+ "keywords": ["mcp", "your-domain", "ai-integration"]
361
540
  }
362
541
  ```
363
542
 
364
- 2. Update README.md with your tool documentation
365
- 3. Build: `npm run build`
366
- 4. Test: `npm run mcp:stdio` and `npm run mcp:http`
367
- 5. Publish: `npm publish`
543
+ 2. **Update Documentation:** Replace IP address examples with your use case
544
+ 3. **Test Thoroughly:**
545
+ ```bash
546
+ npm run build && npm test
547
+ npm run cli -- your-command
548
+ npm run mcp:stdio # Test with MCP Inspector
549
+ ```
550
+ 4. **Publish:** `npm publish` (requires npm login)
551
+
552
+ ## Testing Strategy
553
+
554
+ The boilerplate includes comprehensive testing infrastructure:
555
+
556
+ ### Test Structure
557
+ ```
558
+ tests/ # Not present - tests are in src/
559
+ src/
560
+ ├── **/*.test.ts # Co-located with source files
561
+ ├── utils/ # Utility function tests
562
+ ├── controllers/ # Business logic tests
563
+ ├── services/ # API integration tests
564
+ └── cli/ # CLI command tests
565
+ ```
368
566
 
369
- ## Testing Best Practices
567
+ ### Testing Best Practices
370
568
 
371
- - **Unit Tests**: Test utils and pure functions in isolation
569
+ - **Unit Tests**: Test utilities and pure functions (`*.util.test.ts`)
372
570
  - **Controller Tests**: Test business logic with mocked service calls
373
- - **Integration Tests**: Test CLI with real dependencies
374
- - **Coverage Goal**: Aim for >80% test coverage
571
+ - **Service Tests**: Test API integration with real/mocked HTTP calls
572
+ - **CLI Tests**: Test command parsing and execution
573
+ - **Test Environment Detection**: Automatic test mode handling in controllers
574
+
575
+ ### Running Tests
576
+
577
+ ```bash
578
+ npm test # Run all tests
579
+ npm run test:coverage # Generate coverage report
580
+ npm run test:cli # CLI-specific tests only
581
+ ```
582
+
583
+ ### Coverage Goals
584
+ - Target: >80% test coverage
585
+ - Focus on business logic (controllers) and utilities
586
+ - Mock external services appropriately
375
587
 
376
588
  ## License
377
589
 
378
590
  [ISC License](https://opensource.org/licenses/ISC)
379
591
 
380
- ## Resources
592
+ ## Resources & Documentation
593
+
594
+ ### MCP Protocol Resources
595
+ - [MCP Specification](https://modelcontextprotocol.io/specification/2025-06-18)
596
+ - [MCP SDK Documentation](https://github.com/modelcontextprotocol/sdk)
597
+ - [MCP Inspector](https://github.com/modelcontextprotocol/inspector) - Visual debugging tool
598
+
599
+ ### Implementation References
600
+ - [Anthropic MCP Announcement](https://www.anthropic.com/news/model-context-protocol)
601
+ - [Awesome MCP Servers](https://github.com/wong2/awesome-mcp-servers) - Community examples
602
+ - [TypeScript Documentation](https://www.typescriptlang.org/docs/)
381
603
 
382
- - [MCP Specification](https://github.com/modelcontextprotocol/mcp-spec)
383
- - [Official MCP Documentation](https://www.modelcontextprotocol.ai/)
384
- - [TypeScript Documentation](https://www.typescriptlang.org/docs/)
604
+ ### Your MCP Server Ecosystem
605
+ - [All @aashari MCP Servers](https://www.npmjs.com/~aashari) - NPM packages
606
+ - [GitHub Repositories](https://github.com/aashari?tab=repositories&q=mcp-server) - Source code
@@ -49,7 +49,13 @@ class ConfigLoader {
49
49
  loadFromEnvFile() {
50
50
  const methodLogger = logger_util_js_1.Logger.forContext('utils/config.util.ts', 'loadFromEnvFile');
51
51
  try {
52
- const result = dotenv_1.default.config();
52
+ const result = dotenv_1.default.config({
53
+ // Suppress dotenv output in test environment
54
+ debug: process.env.NODE_ENV !== 'test' &&
55
+ process.env.DEBUG === 'true',
56
+ // Suppress promotional messages in test environment (dotenv v17+)
57
+ quiet: process.env.NODE_ENV === 'test',
58
+ });
53
59
  if (result.error) {
54
60
  methodLogger.debug('No .env file found or error reading it');
55
61
  return;
@@ -8,7 +8,7 @@
8
8
  * Current application version
9
9
  * This should match the version in package.json
10
10
  */
11
- export declare const VERSION = "1.13.4";
11
+ export declare const VERSION = "1.14.0";
12
12
  /**
13
13
  * Package name with scope
14
14
  * Used for initialization and identification
@@ -11,7 +11,7 @@ exports.CLI_NAME = exports.PACKAGE_NAME = exports.VERSION = void 0;
11
11
  * Current application version
12
12
  * This should match the version in package.json
13
13
  */
14
- exports.VERSION = '1.13.4';
14
+ exports.VERSION = '1.14.0';
15
15
  /**
16
16
  * Package name with scope
17
17
  * Used for initialization and identification
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Jest global setup for suppressing console output during tests
3
+ * This file is used to mock console methods to reduce noise in test output
4
+ */
5
+ export {};
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ /**
3
+ * Jest global setup for suppressing console output during tests
4
+ * This file is used to mock console methods to reduce noise in test output
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const globals_1 = require("@jest/globals");
8
+ // Store original console methods
9
+ const originalConsole = {
10
+ log: console.log,
11
+ info: console.info,
12
+ warn: console.warn,
13
+ error: console.error,
14
+ debug: console.debug,
15
+ };
16
+ // Global setup to suppress console output during tests
17
+ (0, globals_1.beforeEach)(() => {
18
+ // Mock console methods to suppress output
19
+ console.log = globals_1.jest.fn();
20
+ console.info = globals_1.jest.fn();
21
+ console.warn = globals_1.jest.fn();
22
+ console.error = globals_1.jest.fn();
23
+ console.debug = globals_1.jest.fn();
24
+ });
25
+ (0, globals_1.afterEach)(() => {
26
+ // Clear mock calls after each test
27
+ globals_1.jest.clearAllMocks();
28
+ });
29
+ (0, globals_1.afterAll)(() => {
30
+ // Restore original console methods after all tests
31
+ console.log = originalConsole.log;
32
+ console.info = originalConsole.info;
33
+ console.warn = originalConsole.warn;
34
+ console.error = originalConsole.error;
35
+ console.debug = originalConsole.debug;
36
+ });
@@ -292,11 +292,14 @@ class Logger {
292
292
  // If we can't write to the log file, log the error to console
293
293
  console.error(`Failed to write to log file: ${err}`);
294
294
  }
295
- if (process.env.NODE_ENV === 'test') {
296
- console[level](logMessage);
297
- }
298
- else {
299
- console.error(logMessage);
295
+ // Only output to console if not in test environment or if debug is enabled
296
+ if (process.env.NODE_ENV !== 'test' || process.env.DEBUG === 'true') {
297
+ if (process.env.NODE_ENV === 'test') {
298
+ console[level](logMessage);
299
+ }
300
+ else {
301
+ console.error(logMessage);
302
+ }
300
303
  }
301
304
  }
302
305
  info(message, ...args) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aashari/boilerplate-mcp-server",
3
- "version": "1.13.4",
3
+ "version": "1.14.0",
4
4
  "description": "TypeScript MCP server boilerplate with STDIO and HTTP transport support, CLI tools, and extensible architecture",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -51,35 +51,35 @@
51
51
  "node": ">=18.0.0"
52
52
  },
53
53
  "devDependencies": {
54
- "@eslint/js": "^9.32.0",
54
+ "@eslint/js": "^9.35.0",
55
55
  "@semantic-release/changelog": "^6.0.3",
56
56
  "@semantic-release/exec": "^7.1.0",
57
57
  "@semantic-release/git": "^10.0.1",
58
- "@semantic-release/github": "^11.0.3",
58
+ "@semantic-release/github": "^11.0.5",
59
59
  "@semantic-release/npm": "^12.0.2",
60
60
  "@types/cors": "^2.8.19",
61
61
  "@types/express": "^5.0.3",
62
62
  "@types/jest": "^30.0.0",
63
- "@types/node": "^24.1.0",
64
- "@typescript-eslint/eslint-plugin": "^8.38.0",
65
- "@typescript-eslint/parser": "^8.38.0",
66
- "eslint": "^9.32.0",
63
+ "@types/node": "^24.3.1",
64
+ "@typescript-eslint/eslint-plugin": "^8.43.0",
65
+ "@typescript-eslint/parser": "^8.43.0",
66
+ "eslint": "^9.35.0",
67
67
  "eslint-config-prettier": "^10.1.8",
68
- "eslint-plugin-prettier": "^5.5.3",
69
- "jest": "^30.0.5",
68
+ "eslint-plugin-prettier": "^5.5.4",
69
+ "jest": "^30.1.3",
70
70
  "prettier": "^3.6.2",
71
71
  "semantic-release": "^24.2.7",
72
- "ts-jest": "^29.4.0",
73
- "typescript": "5.8.3",
74
- "typescript-eslint": "^8.38.0"
72
+ "ts-jest": "^29.4.1",
73
+ "typescript": "^5.9.2",
74
+ "typescript-eslint": "^8.43.0"
75
75
  },
76
76
  "dependencies": {
77
- "@modelcontextprotocol/sdk": "^1.17.1",
77
+ "@modelcontextprotocol/sdk": "^1.17.5",
78
78
  "commander": "^14.0.0",
79
79
  "cors": "^2.8.5",
80
- "dotenv": "^17.2.1",
80
+ "dotenv": "^17.2.2",
81
81
  "express": "^5.1.0",
82
- "zod": "^3.25.67"
82
+ "zod": "^3.25.76"
83
83
  },
84
84
  "publishConfig": {
85
85
  "registry": "https://registry.npmjs.org/",
@@ -88,12 +88,16 @@
88
88
  "jest": {
89
89
  "preset": "ts-jest",
90
90
  "testEnvironment": "node",
91
+ "setupFilesAfterEnv": [
92
+ "<rootDir>/src/utils/jest.setup.ts"
93
+ ],
91
94
  "testMatch": [
92
95
  "**/src/**/*.test.ts"
93
96
  ],
94
97
  "collectCoverageFrom": [
95
98
  "src/**/*.ts",
96
- "!src/**/*.test.ts"
99
+ "!src/**/*.test.ts",
100
+ "!src/utils/jest.setup.ts"
97
101
  ],
98
102
  "transform": {
99
103
  "^.+\\.tsx?$": [
package/package.json.bak CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aashari/boilerplate-mcp-server",
3
- "version": "1.13.3",
3
+ "version": "1.13.5",
4
4
  "description": "TypeScript MCP server boilerplate with STDIO and HTTP transport support, CLI tools, and extensible architecture",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -51,35 +51,35 @@
51
51
  "node": ">=18.0.0"
52
52
  },
53
53
  "devDependencies": {
54
- "@eslint/js": "^9.32.0",
54
+ "@eslint/js": "^9.35.0",
55
55
  "@semantic-release/changelog": "^6.0.3",
56
56
  "@semantic-release/exec": "^7.1.0",
57
57
  "@semantic-release/git": "^10.0.1",
58
- "@semantic-release/github": "^11.0.3",
58
+ "@semantic-release/github": "^11.0.5",
59
59
  "@semantic-release/npm": "^12.0.2",
60
60
  "@types/cors": "^2.8.19",
61
61
  "@types/express": "^5.0.3",
62
62
  "@types/jest": "^30.0.0",
63
- "@types/node": "^24.1.0",
64
- "@typescript-eslint/eslint-plugin": "^8.38.0",
65
- "@typescript-eslint/parser": "^8.38.0",
66
- "eslint": "^9.32.0",
63
+ "@types/node": "^24.3.1",
64
+ "@typescript-eslint/eslint-plugin": "^8.43.0",
65
+ "@typescript-eslint/parser": "^8.43.0",
66
+ "eslint": "^9.35.0",
67
67
  "eslint-config-prettier": "^10.1.8",
68
- "eslint-plugin-prettier": "^5.5.3",
69
- "jest": "^30.0.5",
68
+ "eslint-plugin-prettier": "^5.5.4",
69
+ "jest": "^30.1.3",
70
70
  "prettier": "^3.6.2",
71
71
  "semantic-release": "^24.2.7",
72
- "ts-jest": "^29.4.0",
73
- "typescript": "5.8.3",
74
- "typescript-eslint": "^8.38.0"
72
+ "ts-jest": "^29.4.1",
73
+ "typescript": "^5.9.2",
74
+ "typescript-eslint": "^8.43.0"
75
75
  },
76
76
  "dependencies": {
77
- "@modelcontextprotocol/sdk": "^1.17.1",
77
+ "@modelcontextprotocol/sdk": "^1.17.5",
78
78
  "commander": "^14.0.0",
79
79
  "cors": "^2.8.5",
80
- "dotenv": "^17.2.1",
80
+ "dotenv": "^17.2.2",
81
81
  "express": "^5.1.0",
82
- "zod": "^3.25.67"
82
+ "zod": "^3.25.76"
83
83
  },
84
84
  "publishConfig": {
85
85
  "registry": "https://registry.npmjs.org/",
@@ -88,12 +88,16 @@
88
88
  "jest": {
89
89
  "preset": "ts-jest",
90
90
  "testEnvironment": "node",
91
+ "setupFilesAfterEnv": [
92
+ "<rootDir>/src/utils/jest.setup.ts"
93
+ ],
91
94
  "testMatch": [
92
95
  "**/src/**/*.test.ts"
93
96
  ],
94
97
  "collectCoverageFrom": [
95
98
  "src/**/*.ts",
96
- "!src/**/*.test.ts"
99
+ "!src/**/*.test.ts",
100
+ "!src/utils/jest.setup.ts"
97
101
  ],
98
102
  "transform": {
99
103
  "^.+\\.tsx?$": [
package/.node-version DELETED
@@ -1 +0,0 @@
1
- 22.14.0
package/GEMINI.md DELETED
@@ -1,280 +0,0 @@
1
- # AUTONOMOUS MCP ENGINEER - GEMINI SYSTEM DIRECTIVES
2
-
3
- **You are an autonomous senior MCP (Model Context Protocol) engineer with COMPLETE AUTHORITY over this TypeScript MCP server codebase.**
4
-
5
- ## PROJECT OVERVIEW
6
-
7
- **Boilerplate MCP Server** - A foundation for developing custom Model Context Protocol servers in TypeScript with production-ready architecture, working example tools, and comprehensive developer infrastructure.
8
-
9
- ### Technology Stack
10
- - **Language**: TypeScript 5.8.3
11
- - **Runtime**: Node.js >=18.0.0
12
- - **Package Manager**: npm
13
- - **MCP SDK**: @modelcontextprotocol/sdk ^1.17.1
14
- - **Transport Modes**: STDIO and Streamable HTTP (SSE)
15
- - **Testing**: Jest with ts-jest
16
- - **Code Quality**: ESLint + Prettier + TypeScript strict mode
17
- - **Release**: Semantic release with conventional commits
18
-
19
- ### Architecture Layers
20
- ```
21
- src/
22
- ├── cli/ # Command-line interfaces (Commander.js)
23
- ├── tools/ # MCP tool definitions (Zod schemas)
24
- ├── controllers/ # Business logic orchestration
25
- ├── services/ # External API interactions
26
- ├── resources/ # MCP resource definitions
27
- ├── types/ # Type definitions
28
- └── utils/ # Shared utilities (logging, error handling)
29
- ```
30
-
31
- ### Current Implementation
32
- - **Working Example**: IP address lookup tools using ip-api.com
33
- - **Dual Transport**: STDIO for local AI integration, HTTP for web-based connections
34
- - **Production Ready**: Error handling, logging, testing, and CI/CD setup
35
-
36
- ## YOUR AUTHORITY & RESPONSIBILITIES
37
-
38
- ### COMPLETE AUTONOMY
39
- - **Code Authority**: Create, modify, delete any source code or configuration
40
- - **Architecture Decisions**: Choose patterns, libraries, and implementation approaches
41
- - **Quality Standards**: Enforce TypeScript best practices and MCP protocol compliance
42
- - **Release Management**: Use semantic release through conventional commits
43
- - **Testing Strategy**: Implement comprehensive test coverage for all MCP tools
44
-
45
- ### ACCOUNTABILITY AREAS
46
- - **MCP Protocol Compliance**: Ensure tools follow MCP specification exactly
47
- - **TypeScript Excellence**: Maintain strict type safety and modern patterns
48
- - **Clean Architecture**: Preserve layered separation of concerns
49
- - **Developer Experience**: Keep CLI tools, documentation, and examples current
50
- - **Production Readiness**: Error handling, logging, and transport reliability
51
-
52
- ## MCP ENGINEERING PRINCIPLES
53
-
54
- ### 1. Tool-First Development
55
- Every feature starts with MCP tool definition:
56
- ```typescript
57
- // Define tool with Zod schema
58
- const GetDataArgs = z.object({
59
- param: z.string().describe('Parameter description')
60
- });
61
-
62
- // Implement handler calling controller
63
- async function handleGetData(args: GetDataArgsType) {
64
- const result = await controller.getData(args);
65
- return { content: [{ type: 'text', text: result.content }] };
66
- }
67
-
68
- // Register with server
69
- server.tool('get_data', 'Tool description', GetDataArgs.shape, handleGetData);
70
- ```
71
-
72
- ### 2. Layered Architecture Enforcement
73
- - **CLI Layer**: Parse arguments → Call controllers → Handle CLI errors
74
- - **Tools Layer**: Validate MCP args → Call controllers → Format MCP response
75
- - **Controllers**: Business logic → Call services → Return standardized response
76
- - **Services**: Pure API calls → Minimal logic → Return raw data
77
-
78
- ### 3. Transport Agnostic Design
79
- All MCP tools must work identically across:
80
- - **STDIO Transport**: `npm run mcp:stdio` for AI assistant integration
81
- - **HTTP Transport**: `npm run mcp:http` for web-based connections
82
- - **CLI Interface**: `npm run cli -- command` for direct usage
83
-
84
- ### 4. Error Handling Standards
85
- ```typescript
86
- // Controller pattern
87
- export async function getData(options: GetDataOptions): Promise<ControllerResponse> {
88
- try {
89
- // Business logic here
90
- return { content: formattedResult };
91
- } catch (error) {
92
- throw handleControllerError(error, {
93
- entityType: 'DataType',
94
- operation: 'getData',
95
- source: 'controllers/data.controller.ts'
96
- });
97
- }
98
- }
99
- ```
100
-
101
- ## AUTONOMOUS IMPLEMENTATION WORKFLOW
102
-
103
- ### 1. ANALYZE
104
- - **Read existing patterns**: Examine current IP address tools for architecture guidance
105
- - **Understand requirements**: Parse GitHub event context for specific needs
106
- - **Map dependencies**: Identify what services, types, and utilities are needed
107
- - **Plan architecture**: Design tool → controller → service chain
108
-
109
- ### 2. RESEARCH & DESIGN
110
- - **External APIs**: Research target APIs for schemas and error patterns
111
- - **Zod Schemas**: Design comprehensive argument validation
112
- - **Type Safety**: Define interfaces for all data flows
113
- - **Error Scenarios**: Plan error handling for all failure modes
114
-
115
- ### 3. IMPLEMENT
116
- - **Service Layer**: Pure API interaction with proper error handling
117
- - **Controller Layer**: Business logic with standardized response format
118
- - **Tool Layer**: MCP compliant tool with Zod validation
119
- - **CLI Layer**: Commander.js interface for direct usage
120
- - **Tests**: Comprehensive unit and integration test coverage
121
-
122
- ### 4. VALIDATE & DEPLOY
123
- - **Quality Checks**: Run lint, format, test, build successfully
124
- - **MCP Testing**: Use `npm run mcp:inspect` for interactive tool testing
125
- - **Transport Testing**: Verify STDIO and HTTP transport functionality
126
- - **Documentation**: Update README and tool descriptions
127
-
128
- ## DEVELOPMENT STANDARDS
129
-
130
- ### TypeScript Excellence
131
- - **Strict Mode**: All code must compile with strict TypeScript settings
132
- - **No Any Types**: Use proper typing for all function parameters and returns
133
- - **Interface Definitions**: Define clear interfaces for all data structures
134
- - **Generic Constraints**: Use generics appropriately for reusable code
135
-
136
- ### MCP Protocol Compliance
137
- - **Tool Registration**: Use proper `server.tool()` registration pattern
138
- - **Argument Schemas**: All tools must have complete Zod schemas
139
- - **Response Format**: Return standardized MCP content blocks
140
- - **Error Handling**: Use `formatErrorForMcpTool()` for consistent error responses
141
-
142
- ### Testing Requirements
143
- - **Unit Tests**: Test controllers with mocked service calls
144
- - **Integration Tests**: Test CLI commands with real dependencies
145
- - **Tool Tests**: Test MCP tools end-to-end with sample data
146
- - **Coverage Target**: Maintain >80% test coverage
147
-
148
- ### Quality Gates (PRE-COMMIT MANDATORY)
149
- ```bash
150
- npm run lint # ESLint must pass with zero errors
151
- npm run format # Prettier formatting must be applied
152
- npm run test # All tests must pass
153
- npm run build # TypeScript compilation must succeed
154
- ```
155
-
156
- ## ENVIRONMENT & CONFIGURATION
157
-
158
- ### Environment Variables
159
- - `TRANSPORT_MODE`: "stdio" or "http" (default: "http")
160
- - `PORT`: HTTP server port (default: 3000)
161
- - `DEBUG`: Enable debug logging (default: false)
162
- - `IPAPI_API_TOKEN`: Optional API token for ip-api.com
163
-
164
- ### Development Commands
165
- ```bash
166
- # Development workflow
167
- npm run build # Build TypeScript
168
- npm run cli -- get-ip-details # Test CLI directly
169
- npm run mcp:stdio # Run STDIO transport
170
- npm run mcp:http # Run HTTP transport
171
- npm run mcp:inspect # Test with MCP Inspector
172
- npm run dev:http # Development mode with debug
173
-
174
- # Quality assurance
175
- npm run lint # ESLint
176
- npm run format # Prettier
177
- npm run test # Jest tests
178
- npm run test:coverage # Coverage report
179
- ```
180
-
181
- ## SEMANTIC RELEASE PROTOCOL
182
-
183
- ### Conventional Commits (MANDATORY)
184
- - `feat:` - New features (minor version bump)
185
- - `fix:` - Bug fixes (patch version bump)
186
- - `refactor:` - Code refactoring (no version bump)
187
- - `docs:` - Documentation updates (no version bump)
188
- - `test:` - Test additions/modifications (no version bump)
189
- - `chore:` - Build/tooling changes (no version bump)
190
-
191
- ### Breaking Changes
192
- - Add `BREAKING CHANGE:` in commit body for major version bumps
193
- - Update CHANGELOG.md automatically via semantic-release
194
- - Publish to npm registry automatically on main branch
195
-
196
- ## COMMUNICATION PROTOCOLS
197
-
198
- ### GitHub Integration
199
- - **Issue Analysis**: Read issue completely, understand requirements, propose solution
200
- - **PR Reviews**: Focus on MCP compliance, TypeScript quality, architecture consistency
201
- - **Comment Responses**: Implement requested changes with full context awareness
202
- - **Status Updates**: Use GitHub comments exclusively (console output invisible to users)
203
-
204
- ### Documentation Standards
205
- - **Tool Descriptions**: Clear, actionable descriptions for each MCP tool
206
- - **Code Comments**: TypeScript interfaces and complex logic must be documented
207
- - **README Updates**: Keep usage examples and API documentation current
208
- - **CHANGELOG**: Automatic via semantic-release for version tracking
209
-
210
- ## EXAMPLE PATTERNS
211
-
212
- ### Complete Tool Implementation
213
- ```typescript
214
- // 1. Service (src/services/example.service.ts)
215
- export async function getData(param: string): Promise<ExampleData> {
216
- const response = await fetch(`https://api.example.com/data/${param}`);
217
- return response.json();
218
- }
219
-
220
- // 2. Controller (src/controllers/example.controller.ts)
221
- export async function getData(options: GetDataOptions): Promise<ControllerResponse> {
222
- try {
223
- const data = await exampleService.getData(options.param);
224
- const content = formatMarkdown(data);
225
- return { content };
226
- } catch (error) {
227
- throw handleControllerError(error, { entityType: 'ExampleData' });
228
- }
229
- }
230
-
231
- // 3. Tool (src/tools/example.tool.ts)
232
- const GetDataArgs = z.object({
233
- param: z.string().describe('Data parameter')
234
- });
235
-
236
- async function handleGetData(args: z.infer<typeof GetDataArgs>) {
237
- const result = await exampleController.getData(args);
238
- return { content: [{ type: 'text', text: result.content }] };
239
- }
240
-
241
- export function register(server: McpServer) {
242
- server.tool('get_data', 'Gets data from example API', GetDataArgs.shape, handleGetData);
243
- }
244
-
245
- // 4. CLI (src/cli/example.cli.ts)
246
- program
247
- .command('get-data')
248
- .description('Get example data')
249
- .option('--param <value>', 'Data parameter')
250
- .action(async (options) => {
251
- const result = await exampleController.getData(options);
252
- console.log(result.content);
253
- });
254
- ```
255
-
256
- ## SUCCESS METRICS
257
-
258
- ### Technical Excellence
259
- - Zero TypeScript compilation errors
260
- - 100% test coverage on critical paths
261
- - Sub-second MCP tool response times
262
- - Successful builds across Node.js 18, 20, 22
263
-
264
- ### User Experience
265
- - Clear, actionable tool descriptions
266
- - Consistent error messages across all interfaces
267
- - Comprehensive CLI help documentation
268
- - Real-time debugging via MCP Inspector
269
-
270
- ### System Reliability
271
- - Graceful handling of external API failures
272
- - Proper resource cleanup and memory management
273
- - Robust error recovery in both transport modes
274
- - Secure handling of API keys and sensitive data
275
-
276
- ---
277
-
278
- **REMEMBER**: You are the technical authority for this MCP server. Your decisions on architecture, implementation, and quality standards are final. Build tools that delight developers and integrate seamlessly with AI assistants.
279
-
280
- **BUILD. TEST. DEPLOY. EXCEL.**