@aashari/boilerplate-mcp-server 1.1.0 → 1.1.1

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 (37) hide show
  1. package/.releaserc.json +6 -1
  2. package/CHANGELOG.md +10 -0
  3. package/dist/cli/index.js +5 -2
  4. package/dist/cli/index.js.bak +4 -1
  5. package/dist/cli/ipaddress.cli.js +5 -3
  6. package/dist/cli/ipaddress.cli.test.d.ts +1 -0
  7. package/dist/controllers/ipaddress.controller.d.ts +2 -3
  8. package/dist/controllers/ipaddress.controller.js +22 -18
  9. package/dist/controllers/ipaddress.formatter.d.ts +7 -0
  10. package/dist/controllers/ipaddress.formatter.js +22 -0
  11. package/dist/index.d.ts +3 -3
  12. package/dist/index.js +26 -28
  13. package/dist/index.js.bak +26 -28
  14. package/dist/resources/ipaddress.resource.js +6 -2
  15. package/dist/services/vendor.ip-api.com.service.js +18 -26
  16. package/dist/tools/ipaddress.tool.js +30 -5
  17. package/dist/types/common.types.d.ts +71 -0
  18. package/dist/types/common.types.js +7 -0
  19. package/dist/utils/cli.test.util.d.ts +28 -0
  20. package/dist/utils/cli.test.util.js +122 -0
  21. package/dist/utils/config.util.js +13 -10
  22. package/dist/utils/defaults.util.d.ts +26 -0
  23. package/dist/utils/defaults.util.js +38 -0
  24. package/dist/utils/error-handler.util.d.ts +60 -0
  25. package/dist/utils/error-handler.util.js +162 -0
  26. package/dist/utils/error.util.js +6 -3
  27. package/dist/utils/formatter.util.d.ts +57 -0
  28. package/dist/utils/formatter.util.js +188 -0
  29. package/dist/utils/logger.util.d.ts +44 -2
  30. package/dist/utils/logger.util.js +159 -7
  31. package/dist/utils/pagination.util.d.ts +69 -0
  32. package/dist/utils/pagination.util.js +140 -0
  33. package/dist/utils/transport.util.d.ts +36 -0
  34. package/dist/utils/transport.util.js +120 -0
  35. package/package.json +2 -1
  36. package/package.json.bak +2 -1
  37. package/.eslintrc.json +0 -19
package/.releaserc.json CHANGED
@@ -20,7 +20,12 @@
20
20
  [
21
21
  "@semantic-release/git",
22
22
  {
23
- "assets": ["package.json", "CHANGELOG.md", "src/index.ts"],
23
+ "assets": [
24
+ "package.json",
25
+ "CHANGELOG.md",
26
+ "src/index.ts",
27
+ "src/cli/index.ts"
28
+ ],
24
29
  "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
25
30
  }
26
31
  ],
package/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## [1.1.1](https://github.com/aashari/boilerplate-mcp-server/compare/v1.1.0...v1.1.1) (2025-03-27)
2
+
3
+
4
+ ### Performance Improvements
5
+
6
+ * **core:** refactor code structure to align with Atlassian MCP patterns ([090fd56](https://github.com/aashari/boilerplate-mcp-server/commit/090fd5653ab62d70eb75c49828a9876f54cee6fc))
7
+ * **standards:** align codebase with Atlassian MCP server patterns ([8b8eb13](https://github.com/aashari/boilerplate-mcp-server/commit/8b8eb13fd4ce18158e83c4f8c7044ce06287f23e))
8
+ * **tests:** add CLI test infrastructure and ipaddress tests ([ccee308](https://github.com/aashari/boilerplate-mcp-server/commit/ccee308a86e076a67756e9113b481aa3848f40b7))
9
+ * **utils:** implement standardized core utilities and error handling ([6c14a2f](https://github.com/aashari/boilerplate-mcp-server/commit/6c14a2f83397f79cc39f0b7ec70b40e9d9755b9c))
10
+
1
11
  # [1.1.0](https://github.com/aashari/boilerplate-mcp-server/compare/v1.0.3...v1.1.0) (2025-03-23)
2
12
 
3
13
 
package/dist/cli/index.js CHANGED
@@ -8,21 +8,24 @@ const commander_1 = require("commander");
8
8
  const logger_util_js_1 = require("../utils/logger.util.js");
9
9
  const ipaddress_cli_js_1 = __importDefault(require("./ipaddress.cli.js"));
10
10
  // Get the version from package.json
11
- const VERSION = '1.1.0'; // This should match the version in src/index.ts
11
+ const VERSION = '1.1.1'; // This should match the version in src/index.ts
12
12
  const NAME = '@aashari/boilerplate-mcp-server';
13
13
  const DESCRIPTION = 'A boilerplate Model Context Protocol (MCP) server implementation using TypeScript';
14
14
  async function runCli(args) {
15
+ const methodLogger = logger_util_js_1.Logger.forContext('cli/index.ts', 'runCli');
16
+ methodLogger.debug('Processing CLI arguments', args);
15
17
  const program = new commander_1.Command();
16
18
  program.name(NAME).description(DESCRIPTION).version(VERSION);
17
19
  // Register CLI commands
18
20
  ipaddress_cli_js_1.default.register(program);
19
21
  // Handle unknown commands
20
22
  program.on('command:*', (operands) => {
21
- logger_util_js_1.logger.error(`[src/cli/index.ts] Unknown command: ${operands[0]}`);
23
+ methodLogger.error(`Unknown command: ${operands[0]}`);
22
24
  console.log('');
23
25
  program.help();
24
26
  process.exit(1);
25
27
  });
26
28
  // Parse arguments; default to help if no command provided
27
29
  await program.parseAsync(args.length ? args : ['--help'], { from: 'user' });
30
+ methodLogger.debug('CLI command execution completed');
28
31
  }
@@ -12,17 +12,20 @@ const VERSION = '1.0.1'; // This should match the version in src/index.ts
12
12
  const NAME = '@aashari/boilerplate-mcp-server';
13
13
  const DESCRIPTION = 'A boilerplate Model Context Protocol (MCP) server implementation using TypeScript';
14
14
  async function runCli(args) {
15
+ const methodLogger = logger_util_js_1.Logger.forContext('cli/index.ts', 'runCli');
16
+ methodLogger.debug('Processing CLI arguments', args);
15
17
  const program = new commander_1.Command();
16
18
  program.name(NAME).description(DESCRIPTION).version(VERSION);
17
19
  // Register CLI commands
18
20
  ipaddress_cli_js_1.default.register(program);
19
21
  // Handle unknown commands
20
22
  program.on('command:*', (operands) => {
21
- logger_util_js_1.logger.error(`[src/cli/index.ts] Unknown command: ${operands[0]}`);
23
+ methodLogger.error(`Unknown command: ${operands[0]}`);
22
24
  console.log('');
23
25
  program.help();
24
26
  process.exit(1);
25
27
  });
26
28
  // Parse arguments; default to help if no command provided
27
29
  await program.parseAsync(args.length ? args : ['--help'], { from: 'user' });
30
+ methodLogger.debug('CLI command execution completed');
28
31
  }
@@ -11,16 +11,18 @@ const ipaddress_controller_js_1 = __importDefault(require("../controllers/ipaddr
11
11
  * @param program The Commander program instance
12
12
  */
13
13
  function register(program) {
14
- logger_util_js_1.logger.debug(`[src/cli/ipaddress.cli.ts@register] Registering IP address CLI commands...`);
14
+ const methodLogger = logger_util_js_1.Logger.forContext('cli/ipaddress.cli.ts', 'register');
15
+ methodLogger.debug(`Registering IP address CLI commands...`);
15
16
  program
16
17
  .command('get-ip-details')
17
18
  .description('Get details about a specific IP address or the current device')
18
19
  .argument('[ipAddress]', 'IP address to lookup (optional)')
19
20
  .action(async (ipAddress) => {
21
+ const actionLogger = logger_util_js_1.Logger.forContext('cli/ipaddress.cli.ts', 'get-ip-details');
20
22
  try {
21
- logger_util_js_1.logger.debug(`[src/cli/ipaddress.cli.ts@get-ip-details] Fetching IP details for ${ipAddress || 'current device'}...`);
23
+ actionLogger.debug(`Fetching IP details for ${ipAddress || 'current device'}...`);
22
24
  const result = await ipaddress_controller_js_1.default.get(ipAddress);
23
- logger_util_js_1.logger.debug(`[src/cli/ipaddress.cli.ts@get-ip-details] IP details fetched successfully`, result);
25
+ actionLogger.debug(`IP details fetched successfully`, result);
24
26
  console.log(result.content);
25
27
  }
26
28
  catch (error) {
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,5 @@
1
- declare function get(ipAddress?: string): Promise<{
2
- content: string;
3
- }>;
1
+ import { ControllerResponse } from '../types/common.types.js';
2
+ declare function get(ipAddress?: string): Promise<ControllerResponse>;
4
3
  declare const _default: {
5
4
  get: typeof get;
6
5
  };
@@ -5,29 +5,33 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const vendor_ip_api_com_service_js_1 = __importDefault(require("../services/vendor.ip-api.com.service.js"));
7
7
  const logger_util_js_1 = require("../utils/logger.util.js");
8
- const error_util_js_1 = require("../utils/error.util.js");
8
+ const ipaddress_formatter_js_1 = require("./ipaddress.formatter.js");
9
+ const error_handler_util_js_1 = require("../utils/error-handler.util.js");
10
+ const defaults_util_js_1 = require("../utils/defaults.util.js");
9
11
  async function get(ipAddress) {
10
- logger_util_js_1.logger.debug(`[src/controllers/ipaddress.controller.ts@get] Getting IP address details...`);
12
+ const methodLogger = logger_util_js_1.Logger.forContext('controllers/ipaddress.controller.ts', 'get');
13
+ methodLogger.debug(`Getting IP address details...`);
11
14
  try {
15
+ // Create defaults object (even if empty now)
16
+ const defaults = {}; // Placeholder
17
+ // Apply defaults (will just return the empty options object for now)
18
+ const mergedOptions = (0, defaults_util_js_1.applyDefaults)({}, defaults);
19
+ methodLogger.debug('Using options after defaults:', mergedOptions); // Log merged options
12
20
  const ipData = await vendor_ip_api_com_service_js_1.default.get(ipAddress);
13
- logger_util_js_1.logger.debug(`[src/controllers/ipaddress.controller.ts@get] Got the response from the service`, ipData);
14
- const lines = [];
15
- for (const [key, value] of Object.entries(ipData)) {
16
- lines.push(`${key}: ${value}`);
17
- }
18
- return {
19
- content: lines.join('\n'),
20
- };
21
+ methodLogger.debug(`Got the response from the service`, ipData);
22
+ const formattedContent = (0, ipaddress_formatter_js_1.formatIpDetails)(ipData);
23
+ // Return the standard ControllerResponse structure
24
+ return { content: formattedContent };
21
25
  }
22
26
  catch (error) {
23
- // Log the error
24
- logger_util_js_1.logger.error(`[src/controllers/ipaddress.controller.ts@get] Error getting IP details`, error);
25
- // Pass McpErrors through
26
- if (error instanceof error_util_js_1.McpError) {
27
- throw error;
28
- }
29
- // Wrap other errors
30
- throw (0, error_util_js_1.createUnexpectedError)('Failed to get IP address details', error);
27
+ // Use the standardized error handler
28
+ (0, error_handler_util_js_1.handleControllerError)(error, {
29
+ entityType: 'IP Address Details',
30
+ operation: 'retrieving',
31
+ source: 'controllers/ipaddress.controller.ts@get',
32
+ additionalInfo: { ipAddress },
33
+ });
34
+ // handleControllerError always throws, so no return/throw is needed after it.
31
35
  }
32
36
  }
33
37
  exports.default = { get };
@@ -0,0 +1,7 @@
1
+ import { IPDetail } from '../services/vendor.ip-api.com.type.js';
2
+ /**
3
+ * Format IP address details into Markdown.
4
+ * @param ipData - Raw IP details from the ip-api.com service.
5
+ * @returns Formatted Markdown string.
6
+ */
7
+ export declare function formatIpDetails(ipData: IPDetail): string;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatIpDetails = formatIpDetails;
4
+ const formatter_util_js_1 = require("../utils/formatter.util.js"); // Import from the newly created util
5
+ /**
6
+ * Format IP address details into Markdown.
7
+ * @param ipData - Raw IP details from the ip-api.com service.
8
+ * @returns Formatted Markdown string.
9
+ */
10
+ function formatIpDetails(ipData) {
11
+ const lines = [];
12
+ // Add a main heading
13
+ lines.push((0, formatter_util_js_1.formatHeading)(`IP Address Details: ${ipData.query}`, 1));
14
+ lines.push('');
15
+ // Use formatBulletList for the properties
16
+ // First cast to unknown, then to Record<string, unknown> to avoid TypeScript error
17
+ lines.push((0, formatter_util_js_1.formatBulletList)(ipData));
18
+ // Add a timestamp footer
19
+ lines.push('');
20
+ lines.push(`*Details retrieved at ${(0, formatter_util_js_1.formatDate)(new Date())}*`);
21
+ return lines.join('\n');
22
+ }
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { logger } from './utils/logger.util.js';
2
+ import { Logger } from './utils/logger.util.js';
3
3
  import { config } from './utils/config.util.js';
4
4
  export declare function startServer(mode?: 'stdio' | 'sse'): Promise<void>;
5
- export { logger, config };
6
- export * from './utils/error.util.js';
5
+ export { config };
6
+ export { Logger };
package/dist/index.js CHANGED
@@ -1,50 +1,39 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
- };
17
3
  var __importDefault = (this && this.__importDefault) || function (mod) {
18
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
19
5
  };
20
6
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.config = exports.logger = void 0;
7
+ exports.Logger = exports.config = void 0;
22
8
  exports.startServer = startServer;
23
9
  const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
24
10
  const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
25
11
  const logger_util_js_1 = require("./utils/logger.util.js");
26
- Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_util_js_1.logger; } });
12
+ Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_util_js_1.Logger; } });
27
13
  const config_util_js_1 = require("./utils/config.util.js");
28
14
  Object.defineProperty(exports, "config", { enumerable: true, get: function () { return config_util_js_1.config; } });
29
15
  const error_util_js_1 = require("./utils/error.util.js");
30
16
  const index_js_1 = require("./cli/index.js");
31
17
  const ipaddress_tool_js_1 = __importDefault(require("./tools/ipaddress.tool.js"));
32
18
  const ipaddress_resource_js_1 = __importDefault(require("./resources/ipaddress.resource.js"));
19
+ // Create file-level logger
20
+ const indexLogger = logger_util_js_1.Logger.forContext('index.ts');
33
21
  // Define version constant for easier management and consistent versioning
34
- const VERSION = '1.1.0';
22
+ const VERSION = '1.1.1';
35
23
  let serverInstance = null;
36
24
  let transportInstance = null;
37
25
  async function startServer(mode = 'stdio') {
26
+ const methodLogger = logger_util_js_1.Logger.forContext('index.ts', 'startServer');
38
27
  // Load configuration
39
28
  config_util_js_1.config.load();
40
29
  // Enable debug logging if DEBUG is set to true
41
30
  if (config_util_js_1.config.getBoolean('DEBUG')) {
42
- logger_util_js_1.logger.debug('[src/index.ts] Debug mode enabled');
31
+ methodLogger.debug('Debug mode enabled');
43
32
  }
44
33
  // Log the DEBUG value to verify configuration loading
45
- logger_util_js_1.logger.info(`[src/index.ts] DEBUG value: ${process.env.DEBUG}`);
46
- logger_util_js_1.logger.info(`[src/index.ts] IPAPI_API_TOKEN value exists: ${Boolean(process.env.IPAPI_API_TOKEN)}`);
47
- logger_util_js_1.logger.info(`[src/index.ts] Config DEBUG value: ${config_util_js_1.config.get('DEBUG')}`);
34
+ methodLogger.info(`DEBUG value: ${process.env.DEBUG}`);
35
+ methodLogger.info(`IPAPI_API_TOKEN value exists: ${Boolean(process.env.IPAPI_API_TOKEN)}`);
36
+ methodLogger.info(`Config DEBUG value: ${config_util_js_1.config.get('DEBUG')}`);
48
37
  serverInstance = new mcp_js_1.McpServer({
49
38
  name: '@aashari/boilerplate-mcp-server',
50
39
  version: VERSION,
@@ -55,36 +44,45 @@ async function startServer(mode = 'stdio') {
55
44
  else {
56
45
  throw (0, error_util_js_1.createUnexpectedError)('SSE mode is not supported yet');
57
46
  }
58
- logger_util_js_1.logger.info(`[src/index.ts] Starting server with ${mode.toUpperCase()} transport...`);
47
+ methodLogger.info(`Starting server with ${mode.toUpperCase()} transport...`);
59
48
  // register tools
60
49
  ipaddress_tool_js_1.default.register(serverInstance);
50
+ methodLogger.debug('Registered IP address tools');
61
51
  // register resources
62
52
  ipaddress_resource_js_1.default.register(serverInstance);
53
+ methodLogger.debug('Registered IP lookup resources');
63
54
  return serverInstance.connect(transportInstance).catch((err) => {
64
- logger_util_js_1.logger.error(`[src/index.ts] Failed to start server`, err);
55
+ methodLogger.error(`Failed to start server`, err);
65
56
  process.exit(1);
66
57
  });
67
58
  }
68
59
  // Main entry point - this will run when executed directly
69
60
  async function main() {
61
+ const methodLogger = logger_util_js_1.Logger.forContext('index.ts', 'main');
70
62
  // Load configuration
71
63
  config_util_js_1.config.load();
72
64
  // Log the DEBUG value to verify configuration loading
73
- logger_util_js_1.logger.info(`[src/index.ts] DEBUG value: ${process.env.DEBUG}`);
74
- logger_util_js_1.logger.info(`[src/index.ts] IPAPI_API_TOKEN value exists: ${Boolean(process.env.IPAPI_API_TOKEN)}`);
75
- logger_util_js_1.logger.info(`[src/index.ts] Config DEBUG value: ${config_util_js_1.config.get('DEBUG')}`);
65
+ methodLogger.info(`DEBUG value: ${process.env.DEBUG}`);
66
+ methodLogger.info(`IPAPI_API_TOKEN value exists: ${Boolean(process.env.IPAPI_API_TOKEN)}`);
67
+ methodLogger.info(`Config DEBUG value: ${config_util_js_1.config.get('DEBUG')}`);
76
68
  // Check if arguments are provided (CLI mode)
77
69
  if (process.argv.length > 2) {
78
70
  // CLI mode: Pass arguments to CLI runner
71
+ methodLogger.info('Starting in CLI mode');
79
72
  await (0, index_js_1.runCli)(process.argv.slice(2));
73
+ methodLogger.info('CLI execution completed');
80
74
  }
81
75
  else {
82
76
  // MCP Server mode: Start server with default STDIO
77
+ methodLogger.info('Starting in server mode');
83
78
  await startServer();
79
+ methodLogger.info('Server is now running');
84
80
  }
85
81
  }
86
82
  // If this file is being executed directly (not imported), run the main function
87
83
  if (require.main === module) {
88
- main();
84
+ main().catch((err) => {
85
+ indexLogger.error('Unhandled error in main process', err);
86
+ process.exit(1);
87
+ });
89
88
  }
90
- __exportStar(require("./utils/error.util.js"), exports);
package/dist/index.js.bak CHANGED
@@ -1,50 +1,39 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
- };
17
3
  var __importDefault = (this && this.__importDefault) || function (mod) {
18
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
19
5
  };
20
6
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.config = exports.logger = void 0;
7
+ exports.Logger = exports.config = void 0;
22
8
  exports.startServer = startServer;
23
9
  const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
24
10
  const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
25
11
  const logger_util_js_1 = require("./utils/logger.util.js");
26
- Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_util_js_1.logger; } });
12
+ Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_util_js_1.Logger; } });
27
13
  const config_util_js_1 = require("./utils/config.util.js");
28
14
  Object.defineProperty(exports, "config", { enumerable: true, get: function () { return config_util_js_1.config; } });
29
15
  const error_util_js_1 = require("./utils/error.util.js");
30
16
  const index_js_1 = require("./cli/index.js");
31
17
  const ipaddress_tool_js_1 = __importDefault(require("./tools/ipaddress.tool.js"));
32
18
  const ipaddress_resource_js_1 = __importDefault(require("./resources/ipaddress.resource.js"));
19
+ // Create file-level logger
20
+ const indexLogger = logger_util_js_1.Logger.forContext('index.ts');
33
21
  // Define version constant for easier management and consistent versioning
34
- const VERSION = '1.0.3';
22
+ const VERSION = '1.1.0';
35
23
  let serverInstance = null;
36
24
  let transportInstance = null;
37
25
  async function startServer(mode = 'stdio') {
26
+ const methodLogger = logger_util_js_1.Logger.forContext('index.ts', 'startServer');
38
27
  // Load configuration
39
28
  config_util_js_1.config.load();
40
29
  // Enable debug logging if DEBUG is set to true
41
30
  if (config_util_js_1.config.getBoolean('DEBUG')) {
42
- logger_util_js_1.logger.debug('[src/index.ts] Debug mode enabled');
31
+ methodLogger.debug('Debug mode enabled');
43
32
  }
44
33
  // Log the DEBUG value to verify configuration loading
45
- logger_util_js_1.logger.info(`[src/index.ts] DEBUG value: ${process.env.DEBUG}`);
46
- logger_util_js_1.logger.info(`[src/index.ts] IPAPI_API_TOKEN value exists: ${Boolean(process.env.IPAPI_API_TOKEN)}`);
47
- logger_util_js_1.logger.info(`[src/index.ts] Config DEBUG value: ${config_util_js_1.config.get('DEBUG')}`);
34
+ methodLogger.info(`DEBUG value: ${process.env.DEBUG}`);
35
+ methodLogger.info(`IPAPI_API_TOKEN value exists: ${Boolean(process.env.IPAPI_API_TOKEN)}`);
36
+ methodLogger.info(`Config DEBUG value: ${config_util_js_1.config.get('DEBUG')}`);
48
37
  serverInstance = new mcp_js_1.McpServer({
49
38
  name: '@aashari/boilerplate-mcp-server',
50
39
  version: VERSION,
@@ -55,36 +44,45 @@ async function startServer(mode = 'stdio') {
55
44
  else {
56
45
  throw (0, error_util_js_1.createUnexpectedError)('SSE mode is not supported yet');
57
46
  }
58
- logger_util_js_1.logger.info(`[src/index.ts] Starting server with ${mode.toUpperCase()} transport...`);
47
+ methodLogger.info(`Starting server with ${mode.toUpperCase()} transport...`);
59
48
  // register tools
60
49
  ipaddress_tool_js_1.default.register(serverInstance);
50
+ methodLogger.debug('Registered IP address tools');
61
51
  // register resources
62
52
  ipaddress_resource_js_1.default.register(serverInstance);
53
+ methodLogger.debug('Registered IP lookup resources');
63
54
  return serverInstance.connect(transportInstance).catch((err) => {
64
- logger_util_js_1.logger.error(`[src/index.ts] Failed to start server`, err);
55
+ methodLogger.error(`Failed to start server`, err);
65
56
  process.exit(1);
66
57
  });
67
58
  }
68
59
  // Main entry point - this will run when executed directly
69
60
  async function main() {
61
+ const methodLogger = logger_util_js_1.Logger.forContext('index.ts', 'main');
70
62
  // Load configuration
71
63
  config_util_js_1.config.load();
72
64
  // Log the DEBUG value to verify configuration loading
73
- logger_util_js_1.logger.info(`[src/index.ts] DEBUG value: ${process.env.DEBUG}`);
74
- logger_util_js_1.logger.info(`[src/index.ts] IPAPI_API_TOKEN value exists: ${Boolean(process.env.IPAPI_API_TOKEN)}`);
75
- logger_util_js_1.logger.info(`[src/index.ts] Config DEBUG value: ${config_util_js_1.config.get('DEBUG')}`);
65
+ methodLogger.info(`DEBUG value: ${process.env.DEBUG}`);
66
+ methodLogger.info(`IPAPI_API_TOKEN value exists: ${Boolean(process.env.IPAPI_API_TOKEN)}`);
67
+ methodLogger.info(`Config DEBUG value: ${config_util_js_1.config.get('DEBUG')}`);
76
68
  // Check if arguments are provided (CLI mode)
77
69
  if (process.argv.length > 2) {
78
70
  // CLI mode: Pass arguments to CLI runner
71
+ methodLogger.info('Starting in CLI mode');
79
72
  await (0, index_js_1.runCli)(process.argv.slice(2));
73
+ methodLogger.info('CLI execution completed');
80
74
  }
81
75
  else {
82
76
  // MCP Server mode: Start server with default STDIO
77
+ methodLogger.info('Starting in server mode');
83
78
  await startServer();
79
+ methodLogger.info('Server is now running');
84
80
  }
85
81
  }
86
82
  // If this file is being executed directly (not imported), run the main function
87
83
  if (require.main === module) {
88
- main();
84
+ main().catch((err) => {
85
+ indexLogger.error('Unhandled error in main process', err);
86
+ process.exit(1);
87
+ });
89
88
  }
90
- __exportStar(require("./utils/error.util.js"), exports);
@@ -11,12 +11,16 @@ const ipaddress_controller_js_1 = __importDefault(require("../controllers/ipaddr
11
11
  * @param server The MCP server instance
12
12
  */
13
13
  function register(server) {
14
- logger_util_js_1.logger.debug(`[src/resources/iplookup.resource.ts@register] Registering IP lookup resources...`);
14
+ const methodLogger = logger_util_js_1.Logger.forContext('resources/ipaddress.resource.ts', 'register');
15
+ methodLogger.debug(`Registering IP lookup resources...`);
15
16
  server.resource('Current Device IP', 'ip://current', {
16
17
  description: 'Details about your current IP address',
17
18
  }, async (_uri, _extra) => {
19
+ const resourceMethodLogger = logger_util_js_1.Logger.forContext('resources/ipaddress.resource.ts', 'resourceHandler');
18
20
  try {
21
+ resourceMethodLogger.debug('Handling request for current IP details');
19
22
  const resourceContent = await ipaddress_controller_js_1.default.get();
23
+ resourceMethodLogger.debug('Successfully retrieved IP details');
20
24
  return {
21
25
  contents: [
22
26
  {
@@ -29,7 +33,7 @@ function register(server) {
29
33
  };
30
34
  }
31
35
  catch (error) {
32
- logger_util_js_1.logger.error(`[src/resources/ipaddress.resource.ts] Error getting IP details`, error);
36
+ resourceMethodLogger.error(`Error getting IP details`, error);
33
37
  return (0, error_util_js_1.formatErrorForMcpResource)(error, 'ip://current');
34
38
  }
35
39
  });
@@ -1,43 +1,35 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const logger_util_js_1 = require("../utils/logger.util.js");
4
- const config_util_js_1 = require("../utils/config.util.js");
5
4
  const error_util_js_1 = require("../utils/error.util.js");
6
- const ENDPOINT = 'http://ip-api.com/json';
5
+ const transport_util_js_1 = require("../utils/transport.util.js");
6
+ // Create a contextualized logger for this file
7
+ const serviceLogger = logger_util_js_1.Logger.forContext('services/vendor.ip-api.com.service.ts');
8
+ // Log service initialization
9
+ serviceLogger.debug('IP API service initialized');
7
10
  async function get(ipAddress) {
8
- logger_util_js_1.logger.debug(`[src/services/vendor.ip-api.com.ts@get] Calling the API...`);
9
- // Get API token from configuration
10
- const apiToken = config_util_js_1.config.get('IPAPI_API_TOKEN');
11
- // Build URL with token if available
12
- let url = `${ENDPOINT}/${ipAddress ?? ''}`;
13
- if (apiToken) {
14
- url += `?key=${apiToken}`;
15
- logger_util_js_1.logger.debug(`[src/services/vendor.ip-api.com.ts@get] Using API token`);
16
- }
11
+ const methodLogger = logger_util_js_1.Logger.forContext('services/vendor.ip-api.com.service.ts', 'get');
12
+ methodLogger.debug(`Calling IP API for IP: ${ipAddress || 'current'}`);
17
13
  try {
18
- const response = await fetch(url);
19
- // Handle HTTP errors
20
- if (!response.ok) {
21
- throw (0, error_util_js_1.createApiError)(`IP API request failed: ${response.status} ${response.statusText}`, response.status);
22
- }
23
- const data = (await response.json());
24
- // Handle API-level errors
14
+ // Use the centralized fetchIpApi utility
15
+ // Explicitly type the expected response structure
16
+ const data = await (0, transport_util_js_1.fetchIpApi)(ipAddress || '');
17
+ // Handle API-level success/failure specific to ip-api.com
25
18
  if (data.status !== 'success') {
26
19
  throw (0, error_util_js_1.createApiError)(`IP API error: ${data.message || 'Unknown error'}`);
27
20
  }
28
- return data;
21
+ methodLogger.debug(`Received successful data from IP API`);
22
+ return data; // Already validated as IPDetail structure implicitly by status check
29
23
  }
30
24
  catch (error) {
31
- // Rethrow McpErrors
25
+ // Log the error caught at the service level
26
+ methodLogger.error(`Service error fetching IP data`, error);
27
+ // Rethrow McpErrors (could be from fetchApi or the status check)
32
28
  if (error instanceof error_util_js_1.McpError) {
33
29
  throw error;
34
30
  }
35
- // Handle fetch errors
36
- if (error instanceof TypeError) {
37
- throw (0, error_util_js_1.createApiError)('Network error while contacting IP API', undefined, error);
38
- }
39
- // Handle unexpected errors
40
- throw (0, error_util_js_1.createUnexpectedError)('Unexpected error while fetching IP data', error);
31
+ // Wrap any other unexpected errors
32
+ throw (0, error_util_js_1.createUnexpectedError)('Unexpected service error while fetching IP data', error);
41
33
  }
42
34
  }
43
35
  exports.default = { get };
@@ -8,10 +8,11 @@ const ipaddress_type_js_1 = require("./ipaddress.type.js");
8
8
  const error_util_js_1 = require("../utils/error.util.js");
9
9
  const ipaddress_controller_js_1 = __importDefault(require("../controllers/ipaddress.controller.js"));
10
10
  async function getIpAddressDetails(args, _extra) {
11
- logger_util_js_1.logger.debug(`[src/tools/ipaddress.tool.ts@getIpAddressDetails] Getting IP address details...`);
11
+ const methodLogger = logger_util_js_1.Logger.forContext('tools/ipaddress.tool.ts', 'getIpAddressDetails');
12
+ methodLogger.debug(`Getting IP address details...`);
12
13
  try {
13
14
  const message = await ipaddress_controller_js_1.default.get(args.ipAddress);
14
- logger_util_js_1.logger.debug(`[src/tools/ipaddress.tool.ts@getIpAddressDetails] Got the response from the controller`, message);
15
+ methodLogger.debug(`Got the response from the controller`, message);
15
16
  return {
16
17
  content: [
17
18
  {
@@ -22,12 +23,36 @@ async function getIpAddressDetails(args, _extra) {
22
23
  };
23
24
  }
24
25
  catch (error) {
25
- logger_util_js_1.logger.error(`[src/tools/ipaddress.tool.ts@getIpAddressDetails] Error getting details for IP: ${args.ipAddress || 'current IP'}`, error);
26
+ methodLogger.error(`Error getting details for IP: ${args.ipAddress || 'current IP'}`, error);
26
27
  return (0, error_util_js_1.formatErrorForMcpTool)(error);
27
28
  }
28
29
  }
29
30
  function register(server) {
30
- logger_util_js_1.logger.debug(`[src/tools/ipaddress.ts@register] Registering tools...`);
31
- server.tool('get-ip-details', 'Get details about a specific IP address or the current device (if no IP address is provided)', ipaddress_type_js_1.IpAddressToolArgs.shape, getIpAddressDetails);
31
+ const methodLogger = logger_util_js_1.Logger.forContext('tools/ipaddress.tool.ts', 'register');
32
+ methodLogger.debug(`Registering tools...`);
33
+ server.tool('get-ip-details', `Get details about a specific IP address or the current device's public IP address.
34
+
35
+ PURPOSE: Retrieves geolocation information (country, city, region, coordinates), ISP, and organization details associated with an IP address.
36
+
37
+ WHEN TO USE:
38
+ - To find the geographical location of a given IP address.
39
+ - To identify the ISP or organization owning an IP address.
40
+ - To get your own public IP address details (by omitting the 'ipAddress' argument).
41
+
42
+ WHEN NOT TO USE:
43
+ - For internal/private IP addresses (this tool queries a public database).
44
+ - When you need historical IP data (this provides current lookup).
45
+ - For operations other than retrieving IP geolocation details.
46
+
47
+ RETURNS: Formatted Markdown containing details such as country, city, region, latitude, longitude, ISP, organization, and the queried IP itself.
48
+
49
+ EXAMPLES:
50
+ - Get details for a specific IP: { ipAddress: "8.8.8.8" }
51
+ - Get details for the current device's IP: {}
52
+
53
+ ERRORS:
54
+ - Invalid IP format: If the provided 'ipAddress' is not a valid IP.
55
+ - Private/Reserved IP: If the IP address is in a private range.
56
+ - API errors: If the external ip-api.com service fails.`, ipaddress_type_js_1.IpAddressToolArgs.shape, getIpAddressDetails);
32
57
  }
33
58
  exports.default = { register };