@aashari/boilerplate-mcp-server 1.1.1 → 1.1.3

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.1.3](https://github.com/aashari/boilerplate-mcp-server/compare/v1.1.2...v1.1.3) (2025-03-28)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * correct TypeScript errors in transport utility ([573a7e6](https://github.com/aashari/boilerplate-mcp-server/commit/573a7e63e1985aa5aefd806c0902462fa34c14d7))
7
+
8
+ ## [1.1.2](https://github.com/aashari/boilerplate-mcp-server/compare/v1.1.1...v1.1.2) (2025-03-28)
9
+
10
+
11
+ ### Performance Improvements
12
+
13
+ * **ipaddress:** enhance formatter output and optimize service implementation ([f1ccdbf](https://github.com/aashari/boilerplate-mcp-server/commit/f1ccdbf58cb2518ca979363369904255e5de275b))
14
+
1
15
  ## [1.1.1](https://github.com/aashari/boilerplate-mcp-server/compare/v1.1.0...v1.1.1) (2025-03-27)
2
16
 
3
17
 
package/README.md CHANGED
@@ -1,215 +1,199 @@
1
1
  # Boilerplate MCP Server
2
2
 
3
- ## About
3
+ This project provides a Model Context Protocol (MCP) server template that serves as a starting point for building your own connections between AI assistants (like Anthropic's Claude, Cursor AI, or other MCP-compatible clients) and external data sources or APIs. It includes a working IP lookup tool example to demonstrate the pattern.
4
4
 
5
- This project is a customizable Model Context Protocol (MCP) server written in TypeScript, designed to extend AI assistants like Claude or Cursor with external tools and data sources. MCP is an open-source protocol by Anthropic for connecting AI systems to external capabilities securely and efficiently. For more details on MCP, see [https://modelcontextprotocol.io/docs/](https://modelcontextprotocol.io/docs/). This boilerplate provides a starting point with an IP lookup tool, CLI support, and a flexible architecture for adding your own features.
5
+ ## What is MCP and Why Use This Template?
6
6
 
7
- ## Project Features
7
+ Model Context Protocol (MCP) is an open standard enabling AI models to connect securely to external tools and data sources. This server implements the MCP standard with a flexible architecture for building custom tools.
8
8
 
9
- - **MCP Server**: Exposes tools and resources to AI clients (e.g., Claude Desktop, Cursor AI) via STDIO or HTTP.
10
- - **IP Address Lookup**: Includes an example tool (`get-ip-details`) for fetching IP details, configurable with [ipapi.co](https://ipapi.co).
11
- - **CLI Support**: Run tools directly from the command line without an AI client.
12
- - **Flexible Configuration**: Supports direct environment variables for quick use or a global config file at `$HOME/.mcp/configs.json` for managing multiple servers.
13
- - **Development Tools**: Built-in MCP Inspector for debugging, plus testing and linting utilities.
9
+ **Benefits:**
14
10
 
15
- ### Available Tools
11
+ - **Quick Start:** Begin with a fully-functional MCP server structure including CLI support.
12
+ - **Proven Patterns:** Follow established architecture patterns used in production MCP servers.
13
+ - **Complete Example:** Includes a working IP lookup tool demonstrating the full pattern from CLI to API.
14
+ - **Modern TypeScript:** Built with TypeScript and modern Node.js practices for type safety and maintainability.
15
+ - **Testing Support:** Includes test infrastructure for both unit and CLI integration tests.
16
16
 
17
- - **`get-ip-details`**: Get information about an IP address or the current device's IP.
17
+ ## Available Tools
18
18
 
19
- ## User Guide
19
+ This MCP server provides the following example tool for your AI assistant:
20
20
 
21
- ### Configuration Options
21
+ - **Get IP Address Details (`get-ip-details`)**
22
22
 
23
- - **DEBUG**: Set to `true` for detailed logging (default: `false`).
24
- - **IPAPI_API_TOKEN**: Optional API token for [ipapi.co](https://ipapi.co) to enhance IP lookups (basic lookups work without it).
23
+ - **Purpose:** Retrieves geolocation information (country, city, region, coordinates), ISP, and organization details associated with an IP address.
24
+ - **Use When:** You need to find the geographical location of a given IP address, identify the ISP/organization owning an IP, or get your own public IP details.
25
+ - **Conversational Example:** "What's my public IP and where is it located?" or "Look up the location of IP 8.8.8.8"
26
+ - **Parameter Example:** `{}` (no parameters for current device IP) or `{ ipAddress: "8.8.8.8" }` (specific IP)
25
27
 
26
- #### Method 1: Environment Variables
28
+ ## Interface Philosophy: Simple Input, Rich Output
27
29
 
28
- Pass configs directly when running:
30
+ This server follows a "Minimal Interface, Maximal Detail" approach:
29
31
 
30
- ```bash
31
- DEBUG=true IPAPI_API_TOKEN=your_token npx -y @aashari/boilerplate-mcp-server
32
- ```
32
+ 1. **Simple Tools:** Ask for only essential identifiers or parameters (like `ipAddress`).
33
+ 2. **Rich Details:** Provides comprehensive information in a well-formatted Markdown response.
33
34
 
34
- #### Method 2: Global Config File (Recommended)
35
+ ## Prerequisites
35
36
 
36
- Create `$HOME/.mcp/configs.json`:
37
+ - **Node.js and npm:** Ensure you have Node.js (which includes npm) installed. Download from [nodejs.org](https://nodejs.org/).
38
+ - **IP API Token (Optional):** For enhanced IP lookup capabilities, you can obtain a token from [ip-api.com](https://ip-api.com/) (basic lookups work without a token).
37
39
 
38
- ```json
39
- {
40
- "@aashari/boilerplate-mcp-server": {
41
- "environments": {
42
- "DEBUG": "true",
43
- "IPAPI_API_TOKEN": "your_token"
44
- }
45
- }
46
- }
47
- ```
40
+ ## Quick Start Guide
48
41
 
49
- You can also configure multiple MCP servers in the same file:
50
-
51
- ```json
52
- {
53
- "@aashari/boilerplate-mcp-server": {
54
- "environments": {
55
- "DEBUG": "true",
56
- "IPAPI_API_TOKEN": "your_token"
57
- }
58
- },
59
- "@aashari/mcp-server-atlassian-confluence": {
60
- "environments": {
61
- "DEBUG": "true",
62
- "ATLASSIAN_SITE_NAME": "your-instance",
63
- "ATLASSIAN_USER_EMAIL": "your-email@example.com",
64
- "ATLASSIAN_API_TOKEN": "your_api_token"
65
- }
66
- },
67
- "@aashari/mcp-server-atlassian-jira": {
68
- "environments": {
69
- "DEBUG": "true",
70
- "ATLASSIAN_SITE_NAME": "your-instance",
71
- "ATLASSIAN_USER_EMAIL": "your-email@example.com",
72
- "ATLASSIAN_API_TOKEN": "your_api_token"
73
- }
74
- }
75
- }
76
- ```
42
+ Follow these steps to connect your AI assistant to this boilerplate server:
43
+
44
+ ### Step 1: Configure the Server (Optional)
45
+
46
+ The server works without configuration, but for enhanced options:
77
47
 
78
- ### Using with Claude Desktop
79
-
80
- 1. **Open Settings**:
81
- - Launch Claude Desktop, click the gear icon (top-right).
82
- 2. **Edit Config**:
83
- - Click "Edit Config" to open `claude_desktop_config.json` (e.g., `~/Library/Application Support/Claude` on macOS or `%APPDATA%\Claude` on Windows).
84
- 3. **Add Server**:
85
- - Use the global config file (recommended):
86
- ```json
87
- {
88
- "mcpServers": {
89
- "aashari/boilerplate-mcp-server": {
90
- "command": "npx",
91
- "args": ["-y", "@aashari/boilerplate-mcp-server"]
92
- }
93
- }
94
- }
95
- ```
96
- - Or configure directly:
97
- ```json
98
- {
99
- "mcpServers": {
100
- "aashari/boilerplate-mcp-server": {
101
- "command": "npx",
102
- "args": [
103
- "-y",
104
- "DEBUG=true",
105
- "IPAPI_API_TOKEN=your_token",
106
- "@aashari/boilerplate-mcp-server"
107
- ]
108
- }
109
- }
110
- }
111
- ```
112
- 4. **Restart**: Close and reopen Claude Desktop.
113
- 5. **Test**: Click the hammer icon, verify `get-ip-details` is listed, then ask: "What's my public IP?" or "Get details for IP 8.8.8.8".
114
-
115
- ### Using with Cursor AI
116
-
117
- 1. **Open Settings**:
118
- - Launch Cursor, press `CMD + SHIFT + P` (or `CTRL + SHIFT + P`), select "Cursor Settings" > "MCP".
119
- 2. **Add Server**:
120
- - Click "+ Add new MCP server".
121
- - **Name**: `aashari/boilerplate-mcp-server`.
122
- - **Type**: `command`.
123
- - **Command**:
124
- - Global config: `npx -y @aashari/boilerplate-mcp-server`.
125
- - Direct: `DEBUG=true IPAPI_API_TOKEN=your_token npx -y @aashari/boilerplate-mcp-server`.
126
- - Click "Add".
127
- 3. **Verify**: Check for a green indicator and `get-ip-details` tool listed.
128
- 4. **Test**: In Agent mode, ask: "What's my public IP?" or "Get information about IP 8.8.8.8".
129
-
130
- ### Using as a CLI Tool
131
-
132
- Run without installation:
48
+ #### Method A: Global MCP Config File (Recommended)
49
+
50
+ This keeps configurations separate and organized.
51
+
52
+ 1. **Create the directory** (if needed): `~/.mcp/`
53
+ 2. **Create/Edit the file:** `~/.mcp/configs.json`
54
+ 3. **Add the configuration:** Paste the following JSON structure, replacing the placeholders:
55
+
56
+ ```json
57
+ {
58
+ "@aashari/boilerplate-mcp-server": {
59
+ "environments": {
60
+ "DEBUG": "true",
61
+ "IPAPI_API_TOKEN": "<YOUR_OPTIONAL_IP_API_TOKEN>"
62
+ }
63
+ }
64
+ // Add other servers here if needed
65
+ }
66
+ ```
67
+
68
+ #### Method B: Environment Variables (Alternative)
69
+
70
+ Set environment variables when running the server.
133
71
 
134
72
  ```bash
135
- # Help
136
- npx -y @aashari/boilerplate-mcp-server -- --help
137
- # Current IP
138
- npx -y @aashari/boilerplate-mcp-server -- get-ip-details
139
- # Specific IP
140
- npx -y @aashari/boilerplate-mcp-server -- get-ip-details 8.8.8.8
73
+ DEBUG=true IPAPI_API_TOKEN="<YOUR_OPTIONAL_TOKEN>" npx -y @aashari/boilerplate-mcp-server
141
74
  ```
142
75
 
143
- Or install globally:
76
+ ### Step 2: Connect Your AI Assistant
77
+
78
+ Configure your MCP client (Claude Desktop, Cursor, etc.) to run this server.
79
+
80
+ #### Claude Desktop
81
+
82
+ 1. Open Settings (gear icon) > Edit Config.
83
+ 2. Add or merge into `mcpServers`:
84
+
85
+ ```json
86
+ {
87
+ "mcpServers": {
88
+ "aashari/boilerplate-mcp-server": {
89
+ "command": "npx",
90
+ "args": ["-y", "@aashari/boilerplate-mcp-server"]
91
+ }
92
+ // ... other servers
93
+ }
94
+ }
95
+ ```
96
+
97
+ 3. Save and **Restart Claude Desktop**.
98
+ 4. **Verify:** Click the "Tools" (hammer) icon; the IP lookup tool should be listed.
99
+
100
+ #### Cursor AI
101
+
102
+ 1. Command Palette (`Cmd+Shift+P` / `Ctrl+Shift+P`) > **Cursor Settings > MCP**.
103
+ 2. Click **+ Add new MCP server**.
104
+ 3. Enter:
105
+ - Name: `aashari/boilerplate-mcp-server`
106
+ - Type: `command`
107
+ - Command: `npx -y @aashari/boilerplate-mcp-server`
108
+ 4. Click **Add**.
109
+ 5. **Verify:** Wait for the indicator next to the server name to turn green.
110
+
111
+ ### Step 3: Using the Tools
112
+
113
+ You can now ask your AI assistant IP-related questions:
114
+
115
+ - "What's my public IP address and where is it located?"
116
+ - "Can you get details for IP 8.8.8.8?"
117
+ - "Look up the geolocation of 1.1.1.1"
118
+
119
+ ## Using as a Command-Line Tool (CLI)
120
+
121
+ You can also use this package directly from your terminal:
122
+
123
+ #### Quick Use with `npx`
144
124
 
145
125
  ```bash
146
- npm install -g @aashari/boilerplate-mcp-server
126
+ npx -y @aashari/boilerplate-mcp-server get-ip-details
127
+ npx -y @aashari/boilerplate-mcp-server get-ip-details 8.8.8.8
128
+ npx -y @aashari/boilerplate-mcp-server --help
147
129
  ```
148
130
 
149
- Then run:
131
+ #### Global Installation (Optional)
132
+
133
+ 1. `npm install -g @aashari/boilerplate-mcp-server`
134
+ 2. Use the `mcp-server` command:
150
135
 
151
136
  ```bash
152
- # Help
153
- mcp-server --help
154
- # Current IP
155
137
  mcp-server get-ip-details
156
- # Specific IP
157
138
  mcp-server get-ip-details 8.8.8.8
139
+ mcp-server --help # See all commands
158
140
  ```
159
141
 
160
- Use the global config file or prefix with environment variables:
142
+ ## Extending the Project
161
143
 
162
- ```bash
163
- DEBUG=true IPAPI_API_TOKEN=your_token mcp-server get-ip-details
164
- ```
144
+ This boilerplate is designed to be extended with your own custom tools:
165
145
 
166
- ## Developer Guide
146
+ ### Architecture Overview
167
147
 
168
- ### Development Scripts
148
+ The project follows a clean layered architecture:
169
149
 
170
- The project includes several scripts for development and production use:
150
+ - **CLI / Tool Layer** (`src/cli/*.cli.ts`, `src/tools/*.tool.ts`): User interfaces
151
+ - **Controller Layer** (`src/controllers/*.controller.ts`): Business logic
152
+ - **Service Layer** (`src/services/*.service.ts`): External API interactions
153
+ - **Utils** (`src/utils/*.util.ts`): Shared functionality
171
154
 
172
- - **`npm run dev:server`**: Run the server in development mode with MCP Inspector and debug logging.
173
- - **`npm run dev:cli`**: Run CLI commands in development mode with debug logging.
174
- - **`npm run start:server`**: Run the server in production mode with MCP Inspector.
175
- - **`npm run start:cli`**: Run CLI commands in production mode.
155
+ ### Adding Your Own Tools
176
156
 
177
- Example usage:
157
+ 1. **Create a Service** in `src/services/` to interact with your API or data source.
158
+ 2. **Add a Controller** in `src/controllers/` with business logic and type definitions.
159
+ 3. **Implement a Tool** in `src/tools/` that defines the MCP tool interface.
160
+ 4. **Add CLI Support** in `src/cli/` to enable command-line use.
161
+ 5. **Register** your new tool in `src/index.ts`.
162
+
163
+ ## Developer Guide
164
+
165
+ ### Development Scripts
178
166
 
179
167
  ```bash
180
- # Start the server with Inspector and debug logging
168
+ # Start server in development mode (with Inspector & debug logs)
181
169
  npm run dev:server
182
170
 
183
- # Run a CLI command with debug logging
171
+ # Run CLI in development mode
184
172
  npm run dev:cli -- get-ip-details 8.8.8.8
185
173
 
186
- # Start the server with Inspector (no debug)
174
+ # Production mode (server with Inspector)
187
175
  npm run start:server
188
176
 
189
- # Run a CLI command (no debug)
190
- npm run start:cli -- get-ip-details 8.8.8.8
177
+ # Production mode (CLI command)
178
+ npm run start:cli -- get-ip-details
191
179
  ```
192
180
 
193
- ### Extending the Project
194
-
195
- To add custom tools or resources:
196
-
197
- 1. **Services**: Add API/data logic in `src/services`.
198
- 2. **Controllers**: Implement business logic in `src/controllers`.
199
- 3. **Tools**: Define new tools in `src/tools`.
200
- 4. **Resources**: Add data sources in `src/resources`.
201
- 5. **Register**: Update `src/index.ts` with your tools/resources.
202
-
203
- ### Additional Development Tools
181
+ ### Testing and Quality Tools
204
182
 
205
183
  ```bash
206
- # Run tests
184
+ # Run all tests
207
185
  npm test
208
- # Test coverage
186
+
187
+ # Run specific CLI tests
188
+ npm test -- src/cli/ipaddress.cli.test.ts
189
+
190
+ # Generate test coverage report
209
191
  npm run test:coverage
210
- # Lint
192
+
193
+ # Lint code
211
194
  npm run lint
212
- # Format
195
+
196
+ # Format code
213
197
  npm run format
214
198
  ```
215
199
 
@@ -217,9 +201,30 @@ npm run format
217
201
 
218
202
  The MCP Inspector provides a visual interface for debugging and testing your MCP server:
219
203
 
220
- 1. The Inspector starts your MCP server.
221
- 2. It launches a web UI (typically at `http://localhost:5173`).
222
- 3. Use the UI to test tools, view requests/responses, and check errors.
204
+ 1. Run `npm run dev:server` or `npm run start:server`
205
+ 2. The Inspector launches a web UI (typically at `http://localhost:5173`)
206
+ 3. Use the UI to test tools, view requests/responses, and check errors
207
+
208
+ ## Troubleshooting
209
+
210
+ - **Server Not Connecting (in AI Client):**
211
+ - Confirm the command (`npx ...`) in your client's config is correct
212
+ - Check Node.js/npm installation and PATH
213
+ - Run the `npx` command directly in your terminal for errors
214
+ - **IP API Errors:**
215
+ - Basic lookups should work without configuration
216
+ - If using a token, verify `IPAPI_API_TOKEN` is set correctly
217
+ - Some IP ranges (private IPs like 192.168.x.x) may not return results
218
+ - **Enable Debug Logs:** Set `DEBUG=true` environment variable for verbose logging
219
+
220
+ ## For Developers: Contributing
221
+
222
+ Contributions are welcome! If you'd like to contribute:
223
+
224
+ - **Setup:** Clone repo, `npm install`. Use `npm run dev:server` or `npm run dev:cli -- <command>`.
225
+ - **Code Style:** Use `npm run lint` and `npm run format`.
226
+ - **Tests:** Add tests via `npm test`.
227
+ - **Consistency:** Follow existing patterns and the "Minimal Interface, Maximal Detail" philosophy.
223
228
 
224
229
  ## License
225
230
 
package/dist/cli/index.js CHANGED
@@ -8,7 +8,7 @@ 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.1'; // This should match the version in src/index.ts
11
+ const VERSION = '1.1.3'; // 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) {
@@ -8,7 +8,7 @@ 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.0.1'; // This should match the version in src/index.ts
11
+ const VERSION = '1.1.2'; // 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,13 +15,31 @@ function register(program) {
15
15
  methodLogger.debug(`Registering IP address CLI commands...`);
16
16
  program
17
17
  .command('get-ip-details')
18
- .description('Get details about a specific IP address or the current device')
19
- .argument('[ipAddress]', 'IP address to lookup (optional)')
20
- .action(async (ipAddress) => {
18
+ .description(`Get geolocation and network details about an IP address or the current device.
19
+
20
+ PURPOSE: Retrieve comprehensive information about an IP address including geographical location, ISP, organization, and network details.
21
+
22
+ Use Case: Useful for identifying the location of an IP address, determining network ownership, or checking your own public IP information.
23
+
24
+ Output: Formatted Markdown containing location data (country, region, city), network information (ISP, organization, AS number), coordinates, and a link to view the location on a map.
25
+
26
+ Examples:
27
+ $ mcp-ipaddress get-ip-details
28
+ $ mcp-ipaddress get-ip-details 8.8.8.8
29
+ $ mcp-ipaddress get-ip-details 1.1.1.1`)
30
+ .argument('[ipAddress]', 'IP address to lookup (optional, omit for current device)')
31
+ .option('--extended', 'Include extended data like ASN, mobile and proxy detection')
32
+ .option('--https', 'Use HTTPS for API requests (may require paid API key)')
33
+ .action(async (ipAddress, cmdOptions) => {
21
34
  const actionLogger = logger_util_js_1.Logger.forContext('cli/ipaddress.cli.ts', 'get-ip-details');
22
35
  try {
23
- actionLogger.debug(`Fetching IP details for ${ipAddress || 'current device'}...`);
24
- const result = await ipaddress_controller_js_1.default.get(ipAddress);
36
+ actionLogger.debug(`Fetching IP details for ${ipAddress || 'current device'}...`, cmdOptions);
37
+ // Map CLI options to controller options
38
+ const controllerOptions = {
39
+ includeExtendedData: cmdOptions?.extended || false,
40
+ useHttps: cmdOptions?.https || false,
41
+ };
42
+ const result = await ipaddress_controller_js_1.default.get(ipAddress, controllerOptions);
25
43
  actionLogger.debug(`IP details fetched successfully`, result);
26
44
  console.log(result.content);
27
45
  }
@@ -1,5 +1,22 @@
1
1
  import { ControllerResponse } from '../types/common.types.js';
2
- declare function get(ipAddress?: string): Promise<ControllerResponse>;
2
+ import { GetIpOptions } from './ipaddress.types.js';
3
+ /**
4
+ * @namespace IpAddressController
5
+ * @description Controller responsible for handling IP address lookup logic.
6
+ * It orchestrates calls to the ip-api.com service, applies defaults,
7
+ * maps options, and formats the response using the formatter.
8
+ */
9
+ /**
10
+ * @function get
11
+ * @description Fetches details for a specific IP address or the current device's IP.
12
+ * Handles mapping controller options (like includeExtendedData) to service parameters (fields).
13
+ * @memberof IpAddressController
14
+ * @param {string} [ipAddress] - Optional IP address to look up. If omitted, the service will fetch the current device's public IP.
15
+ * @param {GetIpOptions} [options={}] - Optional configuration for the request, such as `includeExtendedData` and `useHttps`.
16
+ * @returns {Promise<ControllerResponse>} A promise that resolves to the standard controller response containing the formatted IP details in Markdown.
17
+ * @throws {McpError} Throws an McpError (handled by `handleControllerError`) if the service call fails or returns an error.
18
+ */
19
+ declare function get(ipAddress?: string, options?: GetIpOptions): Promise<ControllerResponse>;
3
20
  declare const _default: {
4
21
  get: typeof get;
5
22
  };
@@ -8,30 +8,79 @@ const logger_util_js_1 = require("../utils/logger.util.js");
8
8
  const ipaddress_formatter_js_1 = require("./ipaddress.formatter.js");
9
9
  const error_handler_util_js_1 = require("../utils/error-handler.util.js");
10
10
  const defaults_util_js_1 = require("../utils/defaults.util.js");
11
- async function get(ipAddress) {
11
+ /**
12
+ * @namespace IpAddressController
13
+ * @description Controller responsible for handling IP address lookup logic.
14
+ * It orchestrates calls to the ip-api.com service, applies defaults,
15
+ * maps options, and formats the response using the formatter.
16
+ */
17
+ /**
18
+ * @function get
19
+ * @description Fetches details for a specific IP address or the current device's IP.
20
+ * Handles mapping controller options (like includeExtendedData) to service parameters (fields).
21
+ * @memberof IpAddressController
22
+ * @param {string} [ipAddress] - Optional IP address to look up. If omitted, the service will fetch the current device's public IP.
23
+ * @param {GetIpOptions} [options={}] - Optional configuration for the request, such as `includeExtendedData` and `useHttps`.
24
+ * @returns {Promise<ControllerResponse>} A promise that resolves to the standard controller response containing the formatted IP details in Markdown.
25
+ * @throws {McpError} Throws an McpError (handled by `handleControllerError`) if the service call fails or returns an error.
26
+ */
27
+ async function get(ipAddress, options = {}) {
12
28
  const methodLogger = logger_util_js_1.Logger.forContext('controllers/ipaddress.controller.ts', 'get');
13
- methodLogger.debug(`Getting IP address details...`);
29
+ methodLogger.debug(`Getting IP address details for ${ipAddress || 'current device'}...`);
14
30
  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
20
- const ipData = await vendor_ip_api_com_service_js_1.default.get(ipAddress);
31
+ // Define controller defaults
32
+ const defaults = {
33
+ includeExtendedData: false,
34
+ useHttps: false,
35
+ };
36
+ // Apply defaults to provided options
37
+ const mergedOptions = (0, defaults_util_js_1.applyDefaults)(options, defaults);
38
+ methodLogger.debug('Using options after defaults:', mergedOptions);
39
+ // Map controller options to service options
40
+ const serviceOptions = {
41
+ useHttps: mergedOptions.useHttps,
42
+ };
43
+ // If extended data is requested, include additional fields
44
+ if (mergedOptions.includeExtendedData) {
45
+ serviceOptions.fields = [
46
+ 'status',
47
+ 'message',
48
+ 'country',
49
+ 'countryCode',
50
+ 'region',
51
+ 'regionName',
52
+ 'city',
53
+ 'zip',
54
+ 'lat',
55
+ 'lon',
56
+ 'timezone',
57
+ 'isp',
58
+ 'org',
59
+ 'as',
60
+ 'asname',
61
+ 'reverse',
62
+ 'mobile',
63
+ 'proxy',
64
+ 'hosting',
65
+ 'query',
66
+ ];
67
+ }
68
+ // Call the service with the mapped options
69
+ const ipData = await vendor_ip_api_com_service_js_1.default.get(ipAddress, serviceOptions);
21
70
  methodLogger.debug(`Got the response from the service`, ipData);
71
+ // Format the data using the formatter
22
72
  const formattedContent = (0, ipaddress_formatter_js_1.formatIpDetails)(ipData);
23
73
  // Return the standard ControllerResponse structure
24
74
  return { content: formattedContent };
25
75
  }
26
76
  catch (error) {
27
- // Use the standardized error handler
28
- (0, error_handler_util_js_1.handleControllerError)(error, {
77
+ // Use the standardized error handler with return
78
+ return (0, error_handler_util_js_1.handleControllerError)(error, {
29
79
  entityType: 'IP Address Details',
30
80
  operation: 'retrieving',
31
81
  source: 'controllers/ipaddress.controller.ts@get',
32
82
  additionalInfo: { ipAddress },
33
83
  });
34
- // handleControllerError always throws, so no return/throw is needed after it.
35
84
  }
36
85
  }
37
86
  exports.default = { get };
@@ -1,4 +1,4 @@
1
- import { IPDetail } from '../services/vendor.ip-api.com.type.js';
1
+ import { IPDetail } from '../services/vendor.ip-api.com.types.js';
2
2
  /**
3
3
  * Format IP address details into Markdown.
4
4
  * @param ipData - Raw IP details from the ip-api.com service.
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.formatIpDetails = formatIpDetails;
4
- const formatter_util_js_1 = require("../utils/formatter.util.js"); // Import from the newly created util
4
+ const formatter_util_js_1 = require("../utils/formatter.util.js");
5
5
  /**
6
6
  * Format IP address details into Markdown.
7
7
  * @param ipData - Raw IP details from the ip-api.com service.
@@ -12,11 +12,39 @@ function formatIpDetails(ipData) {
12
12
  // Add a main heading
13
13
  lines.push((0, formatter_util_js_1.formatHeading)(`IP Address Details: ${ipData.query}`, 1));
14
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
15
+ // Add a summary section
16
+ lines.push((0, formatter_util_js_1.formatHeading)('Location Information', 2));
17
+ // Format the location information in a structured way
18
+ const locationInfo = {
19
+ Country: `${ipData.country} (${ipData.countryCode})`,
20
+ Region: `${ipData.regionName} (${ipData.region})`,
21
+ City: ipData.city,
22
+ 'Zip/Postal Code': ipData.zip,
23
+ Coordinates: `${ipData.lat}, ${ipData.lon}`,
24
+ Timezone: ipData.timezone,
25
+ };
26
+ lines.push((0, formatter_util_js_1.formatBulletList)(locationInfo));
27
+ lines.push('');
28
+ // Add network information section
29
+ lines.push((0, formatter_util_js_1.formatHeading)('Network Information', 2));
30
+ const networkInfo = {
31
+ 'IP Address': ipData.query,
32
+ ISP: ipData.isp,
33
+ Organization: ipData.org,
34
+ AS: ipData.as,
35
+ };
36
+ lines.push((0, formatter_util_js_1.formatBulletList)(networkInfo));
37
+ // Add a map link if coordinates are available
38
+ if (ipData.lat && ipData.lon) {
39
+ lines.push('');
40
+ lines.push((0, formatter_util_js_1.formatHeading)('Map', 2));
41
+ const mapUrl = `https://www.openstreetmap.org/?mlat=${ipData.lat}&mlon=${ipData.lon}&zoom=12`;
42
+ lines.push(`${(0, formatter_util_js_1.formatUrl)(mapUrl, 'View on OpenStreetMap')}`);
43
+ }
44
+ // Add a separator
19
45
  lines.push('');
46
+ lines.push((0, formatter_util_js_1.formatSeparator)());
47
+ // Add a timestamp footer
20
48
  lines.push(`*Details retrieved at ${(0, formatter_util_js_1.formatDate)(new Date())}*`);
21
49
  return lines.join('\n');
22
50
  }