@isnow890/naver-search-mcp 1.0.45 โ†’ 1.0.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,76 +6,19 @@
6
6
  [![smithery badge](https://smithery.ai/badge/@isnow890/naver-search-mcp)](https://smithery.ai/server/@isnow890/naver-search-mcp)
7
7
  [![MCP.so](https://img.shields.io/badge/MCP.so-Naver%20Search%20MCP-blue)](https://mcp.so/server/naver-search-mcp/isnow890)
8
8
 
9
- #### Version History
9
+ MCP server for Naver Search API and DataLab API integration, enabling comprehensive search across various Naver services and data trend analysis.
10
10
 
11
- ###### 1.0.45 (2025-09-28)
11
+ ## Quick Start: Use Without API Key
12
12
 
13
- - Smithery compatibility issues resolved - Now available through Smithery with latest features
14
- - Excel compatibility issues fixed in category search - Replaced with JSON functionality
15
- - Web Korean search (`search_webkr`) functionality restored
16
- - Full compatibility with Smithery platform installations
17
-
18
- ###### 1.0.44 (2025-08-31)
19
-
20
- - `get_current_korean_time` tool added - Essential time context tool for Korean timezone
21
- - Enhanced all existing tool descriptions to reference time tool for temporal queries
22
- - Improved temporal context handling for "today", "now", "current" searches
23
- - Comprehensive Korean time formatting with multiple output formats
24
-
25
- ###### 1.0.4 (2025-08-21)
26
-
27
- - `find_category` tool added - with fuzzy matching and ranking system support
28
- - Enhanced parameter validation with Zod schema
29
- - Improved category search workflow
30
-
31
- ###### 1.0.30 (2025-08-04)
32
-
33
- - MCP SDK upgraded to 1.17.1
34
- - Fixed compatibility issues with Smithery specification changes
35
- - Added comprehensive DataLab shopping category code documentation
36
-
37
- ###### 1.0.2 (2025-04-26)
38
-
39
- - README updated: cafe article search tool and version history section improved
40
-
41
- ###### 1.0.1 (2025-04-26)
42
-
43
- - Cafe article search feature added
44
- - Shopping category info added to zod
45
- - Source code refactored
46
-
47
- ###### 1.0.0 (2025-04-08)
48
-
49
- - Initial release
50
-
51
- #### Prerequisites
52
-
53
- - Naver Developers API Key (Client ID and Secret)
54
- - Node.js 18 or higher
55
- - NPM 8 or higher
56
- - Docker (optional, for container deployment)
57
-
58
- #### Getting API Keys
59
-
60
- 1. Visit [Naver Developers](https://developers.naver.com/apps/#/register)
61
- 2. Click "Register Application"
62
- 3. Enter application name and select ALL of the following APIs:
63
- - Search (for blog, news, book search, etc.)
64
- - DataLab (Search Trends)
65
- - DataLab (Shopping Insight)
66
- 4. Set the obtained Client ID and Client Secret as environment variables
13
+ You can use this server immediately without API keys through [Kakao PlayMCP](https://playmcp.kakao.com/mcp/154). Simply visit the link and start using it right away!
67
14
 
68
15
  ## Tool Details
69
16
 
70
17
  ### Available tools:
71
18
 
72
- #### ๐Ÿ• Time & Context Tools
73
-
74
- - **get_current_korean_time**: Get current Korean time (KST) with comprehensive date/time information. Essential for understanding "today", "now", or "current" context in Korean timezone. Always use this tool when temporal context is needed for searches or analysis.
75
-
76
19
  #### ๐Ÿ†• Category Search
77
20
 
78
- - **find_category**: Category search tool - No more need to manually check category numbers via URL for trend and shopping insight searches. The LLM will find it out as you say.
21
+ - **find_category**: Category search tool so you no longer need to manually check category numbers in URLs for trend and shopping insight searches. Just describe the category in natural language.
79
22
 
80
23
  #### Search Tools
81
24
 
@@ -103,129 +46,26 @@
103
46
  - **datalab_shopping_keyword_by_gender**: Analyze shopping keyword trends by gender
104
47
  - **datalab_shopping_keyword_by_age**: Analyze shopping keyword trends by age group
105
48
 
106
- #### Complete Category List:
107
-
108
- For a complete list of category codes, you can download from Naver Shopping Partner Center or extract them by browsing Naver Shopping categories.
109
-
110
- ### ๐ŸŽฏ Business Use Cases & Scenarios
111
-
112
- #### ๐Ÿ›๏ธ E-commerce Market Research
113
-
114
- ```javascript
115
- // Fashion trend discovery
116
- find_category("fashion") โ†’ Check top fashion categories and codes
117
- datalab_shopping_category โ†’ Analyze seasonal fashion trends
118
- datalab_shopping_age โ†’ Identify fashion target demographics
119
- datalab_shopping_keywords โ†’ Compare "dress" vs "jacket" vs "coat"
120
- ```
121
-
122
- #### ๐Ÿ“ฑ Digital Marketing Strategy
123
-
124
- ```javascript
125
- // Beauty industry analysis
126
- find_category("cosmetics") โ†’ Find beauty categories
127
- datalab_shopping_gender โ†’ 95% female vs 5% male shoppers
128
- datalab_shopping_device โ†’ Mobile dominance in beauty shopping
129
- datalab_shopping_keywords โ†’ "tint" vs "lipstick" keyword performance
130
- ```
131
-
132
- #### ๐Ÿข Business Intelligence & Competitive Analysis
133
-
134
- ```javascript
135
- // Tech product insights
136
- find_category("smartphone") โ†’ Check electronics categories
137
- datalab_shopping_category โ†’ Track iPhone vs Galaxy trends
138
- datalab_shopping_age โ†’ 20-30s as main smartphone buyers
139
- datalab_shopping_device โ†’ PC vs mobile shopping behavior
140
- ```
141
-
142
- #### ๐Ÿ“Š Seasonal Business Planning
143
-
144
- ```javascript
145
- // Holiday shopping analysis
146
- find_category("gift") โ†’ Gift categories
147
- datalab_shopping_category โ†’ Black Friday, Christmas trends
148
- datalab_shopping_keywords โ†’ "Mother's Day gift" vs "birthday gift"
149
- datalab_shopping_age โ†’ Age-based gift purchasing patterns
150
- ```
151
-
152
- #### ๐ŸŽฏ Customer Persona Development
153
-
154
- ```javascript
155
- // Fitness market analysis
156
- find_category("exercise") โ†’ Sports/fitness categories
157
- datalab_shopping_gender โ†’ Male vs female fitness spending
158
- datalab_shopping_age โ†’ Primary fitness demographics (20-40s)
159
- datalab_shopping_keywords โ†’ "home workout" vs "gym" trend analysis
160
- ```
161
-
162
- ### ๐Ÿ“ˆ Advanced Analysis Scenarios
163
-
164
- #### Market Entry Strategy
165
-
166
- 1. **Category Discovery**: Use `find_category` to explore market segments
167
- 2. **Trend Analysis**: Identify growing vs declining categories
168
- 3. **Demographic Targeting**: Age/gender analysis for customer targeting
169
- 4. **Competitive Intelligence**: Keyword performance comparison
170
- 5. **Device Strategy**: Mobile vs PC shopping optimization
171
-
172
- #### Product Launch Planning
173
-
174
- 1. **Market Validation**: Category growth trends and seasonality
175
- 2. **Target Customers**: Demographic analysis for product positioning
176
- 3. **Marketing Channels**: Device preferences for advertising strategy
177
- 4. **Competitive Landscape**: Keyword competition and opportunities
178
- 5. **Pricing Strategy**: Category performance and price correlation
179
-
180
- #### Performance Monitoring
181
-
182
- 1. **Category Health**: Monitor product category trends
183
- 2. **Keyword Tracking**: Track brand and product keyword performance
184
- 3. **Demographic Shifts**: Monitor changing customer demographics
185
- 4. **Seasonal Patterns**: Plan inventory and marketing campaigns
186
- 5. **Competitive Benchmarking**: Compare performance against category averages
187
-
188
- ### Quick Reference: Popular Category Codes
189
-
190
- | Category | Code | Korean |
191
- | ------------------- | -------- | ------------- |
192
- | Fashion/Clothing | 50000000 | ํŒจ์…˜์˜๋ฅ˜ |
193
- | Cosmetics/Beauty | 50000002 | ํ™”์žฅํ’ˆ/๋ฏธ์šฉ |
194
- | Digital/Electronics | 50000003 | ๋””์ง€ํ„ธ/๊ฐ€์ „ |
195
- | Sports/Leisure | 50000004 | ์Šคํฌ์ธ /๋ ˆ์ € |
196
- | Food/Beverages | 50000008 | ์‹ํ’ˆ/์Œ๋ฃŒ |
197
- | Health/Medical | 50000009 | ๊ฑด๊ฐ•/์˜๋ฃŒ์šฉํ’ˆ |
198
-
199
- ๐Ÿ’ก **Tip**: Use `find_category` with fuzzy searches like "beauty", "fashion", "electronics" to easily find categories.
49
+ ## Getting API Keys
50
+
51
+ 1. Visit [Naver Developers](https://developers.naver.com/apps/#/register) and log in with your Naver account
52
+ 2. Click the "Application Registration" (์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋“ฑ๋ก) button
53
+ 3. Fill in the application information:
54
+ - **Application Name**: Enter any name (e.g., "Naver Search MCP")
55
+ - **Usage**: Select "Search" (๊ฒ€์ƒ‰)
56
+ 4. In the API Settings section, check ALL of the following APIs:
57
+ - **Search** (๊ฒ€์ƒ‰) - Required for blog, news, book, cafe article, web, image, kin, encyclopedia, academic, and local search
58
+ - **DataLab - Search Trends** (๋ฐ์ดํ„ฐ๋žฉ - ๊ฒ€์ƒ‰์–ด ํŠธ๋ Œ๋“œ) - Required for search term trend analysis
59
+ - **DataLab - Shopping Insight** (๋ฐ์ดํ„ฐ๋žฉ - ์‡ผํ•‘์ธ์‚ฌ์ดํŠธ) - Required for shopping trend analysis
60
+ 5. Click "Register" to complete registration
61
+ 6. After registration, you'll see your **Client ID** and **Client Secret** on the application detail page
62
+ 7. Use these credentials in the configuration below
200
63
 
201
64
  ## Installation
202
65
 
203
- ### Method 1: Smithery Installation (Recommended)
204
-
205
- The easiest way to use this MCP server is through Smithery.
66
+ ### Method 1: NPX Installation (Recommended)
206
67
 
207
- #### For Claude Desktop:
208
-
209
- ```bash
210
- npx -y @smithery/cli@latest install @isnow890/naver-search-mcp --client claude
211
- ```
212
-
213
- #### For other AI clients:
214
-
215
- ```bash
216
- # Cursor
217
- npx -y @smithery/cli@latest install @isnow890/naver-search-mcp --client cursor
218
-
219
- # Windsurf
220
- npx -y @smithery/cli@latest install @isnow890/naver-search-mcp --client windsurf
221
-
222
- # Cline
223
- npx -y @smithery/cli@latest install @isnow890/naver-search-mcp --client cline
224
- ```
225
-
226
- ### Method 2: NPX Installation
227
-
228
- Alternatively, you can use NPX installation. For detailed package information, see the [NPM package page](https://www.npmjs.com/package/@isnow890/naver-search-mcp).
68
+ The most reliable way to use this MCP server is through NPX. For detailed package information, see the [NPM package page](https://www.npmjs.com/package/@isnow890/naver-search-mcp).
229
69
 
230
70
  #### Claude Desktop Configuration
231
71
 
@@ -246,9 +86,9 @@ Add to Claude Desktop config file (`%APPDATA%\Claude\claude_desktop_config.json`
246
86
  }
247
87
  ```
248
88
 
249
- #### Cursor AI Configuration
89
+ #### Claude Code Configuration
250
90
 
251
- Add to `mcp.json`:
91
+ Add to your Claude Code settings:
252
92
 
253
93
  ```json
254
94
  {
@@ -265,6 +105,14 @@ Add to `mcp.json`:
265
105
  }
266
106
  ```
267
107
 
108
+ ### Method 2: Smithery Installation
109
+
110
+ Install via Smithery CLI:
111
+
112
+ ```bash
113
+ npx -y @smithery/cli@latest install @isnow890/naver-search-mcp --client claude
114
+ ```
115
+
268
116
  ### Method 3: Local Installation
269
117
 
270
118
  For local development or custom modifications:
@@ -282,7 +130,7 @@ npm run build
282
130
 
283
131
  ##### Or Download ZIP File
284
132
 
285
- 1. Download the latest version from [GitHub Releases](https://github.com/isnow890/naver-search-mcp/releases)
133
+ 1. Download the latest version from [GitHub Releases](https://github.com/isnow890/naver-search-mcp)
286
134
  2. Extract the ZIP file to your desired location
287
135
  3. Navigate to the extracted folder in terminal:
288
136
 
@@ -372,51 +220,66 @@ pwd
372
220
 
373
221
  After completing the configuration, completely close and restart Claude Desktop to activate the Naver Search MCP server.
374
222
 
223
+ ## Prerequisites
224
+
225
+ - Naver Developers API Key (Client ID and Secret)
226
+ - Node.js 18 or higher
227
+ - NPM 8 or higher
228
+
229
+ ## License
230
+
231
+ MIT License
232
+
375
233
  ---
376
234
 
377
- ## Alternative Installation Methods
235
+ ## Version History
378
236
 
379
- ### Method 4: Docker Installation
237
+ ### 1.0.47 (2025-01-03)
380
238
 
381
- For containerized deployment:
239
+ - **Added "today" keyword support** for all DataLab date parameters - no need to call separate time tool
240
+ - **Fixed server termination issue** - MCP server now properly exits when client disconnects
241
+ - **Added graceful shutdown handlers** for SIGINT, SIGTERM, and transport close events
242
+ - **Removed get_current_korean_time tool** - redundant with new "today" keyword feature
243
+ - **Removed memory monitoring module** - resolved setInterval blocking process exit
244
+ - **Special thanks to @gloomyrobot** for reporting the server termination issue
382
245
 
383
- ```bash
384
- docker run -i --rm \
385
- -e NAVER_CLIENT_ID=your_client_id \
386
- -e NAVER_CLIENT_SECRET=your_client_secret \
387
- mcp/naver-search
388
- ```
246
+ ### 1.0.45 (2025-09-28)
389
247
 
390
- Docker configuration for Claude Desktop:
248
+ - Resolved Smithery compatibility issues so you can use the latest features through Smithery
249
+ - Replaced the Excel export in category search with JSON for better compatibility
250
+ - Restored the `search_webkr` tool for Korean web search
251
+ - Fully compatible with Smithery platform installation
391
252
 
392
- ```json
393
- {
394
- "mcpServers": {
395
- "naver-search": {
396
- "command": "docker",
397
- "args": [
398
- "run",
399
- "-i",
400
- "--rm",
401
- "-e",
402
- "NAVER_CLIENT_ID=your_client_id",
403
- "-e",
404
- "NAVER_CLIENT_SECRET=your_client_secret",
405
- "mcp/naver-search"
406
- ]
407
- }
408
- }
409
- }
410
- ```
253
+ ### 1.0.44 (2025-08-31)
411
254
 
412
- ## Build
255
+ - Added the `get_current_korean_time` tool for essential Korea Standard Time context
256
+ - Referenced the time tool across existing tool descriptions for temporal queries
257
+ - Improved handling of "today", "now", and "current" searches with temporal context
258
+ - Expanded Korean date and time formatting outputs with multiple formats
413
259
 
414
- Docker build:
260
+ ### 1.0.40 (2025-08-21)
415
261
 
416
- ```bash
417
- docker build -t mcp/naver-search .
418
- ```
262
+ - Added the `find_category` tool with fuzzy matching so you no longer need to check category numbers manually in URLs
263
+ - Enhanced parameter validation with Zod schema
264
+ - Improved the category search workflow
265
+ - Implemented a level-based category ranking system that prioritizes top-level categories
419
266
 
420
- ## License
267
+ ### 1.0.30 (2025-08-04)
421
268
 
422
- MIT License
269
+ - MCP SDK upgraded to 1.17.1
270
+ - Fixed compatibility issues with Smithery specification changes
271
+ - Added comprehensive DataLab shopping category code documentation
272
+
273
+ ### 1.0.2 (2025-04-26)
274
+
275
+ - README updated: cafe article search tool and version history section improved
276
+
277
+ ### 1.0.1 (2025-04-26)
278
+
279
+ - Cafe article search feature added
280
+ - Shopping category info added to zod
281
+ - Source code refactored
282
+
283
+ ### 1.0.0 (2025-04-08)
284
+
285
+ - Initial release
@@ -0,0 +1,17 @@
1
+ import { AxiosRequestConfig, AxiosInstance } from "axios";
2
+ import { NaverSearchConfig } from "../schemas/search.schemas.js";
3
+ export declare abstract class NaverApiCoreClient {
4
+ protected searchBaseUrl: string;
5
+ protected datalabBaseUrl: string;
6
+ protected config: NaverSearchConfig | null;
7
+ protected axiosInstance: AxiosInstance;
8
+ constructor();
9
+ initialize(config: NaverSearchConfig): void;
10
+ protected getHeaders(contentType?: string): AxiosRequestConfig;
11
+ protected get<T>(url: string, params: any): Promise<T>;
12
+ protected post<T>(url: string, data: any): Promise<T>;
13
+ /**
14
+ * ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ ๋ฉ”์„œ๋“œ (๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€)
15
+ */
16
+ protected cleanup(): void;
17
+ }
@@ -4,6 +4,12 @@ export class NaverApiCoreClient {
4
4
  this.searchBaseUrl = "https://openapi.naver.com/v1/search";
5
5
  this.datalabBaseUrl = "https://openapi.naver.com/v1/datalab";
6
6
  this.config = null;
7
+ // HTTP/HTTPS ์—์ด์ „ํŠธ ์„ค์ •์œผ๋กœ ์—ฐ๊ฒฐ ํ’€๋ง ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€
8
+ this.axiosInstance = axios.create({
9
+ timeout: 30000, // 30์ดˆ ํƒ€์ž„์•„์›ƒ
10
+ maxRedirects: 3,
11
+ // HTTP ์—ฐ๊ฒฐ ํ’€๋ง ์„ค์ •์€ ์šด์˜์ฒด์ œ์—์„œ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋‹จ์ˆœํ™”
12
+ });
7
13
  }
8
14
  initialize(config) {
9
15
  this.config = config;
@@ -20,11 +26,33 @@ export class NaverApiCoreClient {
20
26
  };
21
27
  }
22
28
  async get(url, params) {
23
- const response = await axios.get(url, { params, ...this.getHeaders() });
24
- return response.data;
29
+ try {
30
+ const response = await this.axiosInstance.get(url, {
31
+ params,
32
+ ...this.getHeaders()
33
+ });
34
+ return response.data;
35
+ }
36
+ catch (error) {
37
+ // ์—ฐ๊ฒฐ ์ •๋ฆฌ๋Š” axios๊ฐ€ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์ง€๋งŒ ๋ช…์‹œ์ ์œผ๋กœ ์—๋Ÿฌ ์ฒ˜๋ฆฌ
38
+ throw error;
39
+ }
25
40
  }
26
41
  async post(url, data) {
27
- const response = await axios.post(url, data, this.getHeaders());
28
- return response.data;
42
+ try {
43
+ const response = await this.axiosInstance.post(url, data, this.getHeaders());
44
+ return response.data;
45
+ }
46
+ catch (error) {
47
+ // ์—ฐ๊ฒฐ ์ •๋ฆฌ๋Š” axios๊ฐ€ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์ง€๋งŒ ๋ช…์‹œ์ ์œผ๋กœ ์—๋Ÿฌ ์ฒ˜๋ฆฌ
48
+ throw error;
49
+ }
50
+ }
51
+ /**
52
+ * ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ ๋ฉ”์„œ๋“œ (๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€)
53
+ */
54
+ cleanup() {
55
+ // ์—ฐ๊ฒฐ ์ •๋ฆฌ - axios๊ฐ€ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌ
56
+ this.config = null;
29
57
  }
30
58
  }
@@ -0,0 +1,78 @@
1
+ import { NaverApiCoreClient } from "./naver-api-core.client.js";
2
+ import { NaverSearchType, NaverSearchConfig, NaverLocalSearchParams, NaverDocumentSearchParams, SearchArgs } from "../schemas/search.schemas.js";
3
+ import { NaverDocumentSearchResponse, NaverLocalSearchResponse } from "../types/search.types.js";
4
+ import { DatalabSearchRequest, DatalabShoppingResponse, DatalabShoppingCategoryRequest, DatalabShoppingDeviceRequest, DatalabShoppingGenderRequest, DatalabShoppingAgeRequest, DatalabShoppingKeywordsRequest, DatalabShoppingKeywordRequest } from "../types/datalab.types.js";
5
+ /**
6
+ * NaverSearchClient - ๋„ค์ด๋ฒ„ API ์„œ๋น„์Šค๋ฅผ ์œ„ํ•œ ์‹ฑ๊ธ€ํ†ค ํด๋ผ์ด์–ธํŠธ
7
+ * ๊ฒ€์ƒ‰, ๋ฐ์ดํ„ฐ๋žฉ API ์š”์ฒญ ์ฒ˜๋ฆฌ
8
+ */
9
+ export declare class NaverSearchClient extends NaverApiCoreClient {
10
+ private static instance;
11
+ private constructor();
12
+ /**
13
+ * ์‹ฑ๊ธ€ํ†ค ์ธ์Šคํ„ด์Šค ๋ฐ˜ํ™˜
14
+ */
15
+ static getInstance(): NaverSearchClient;
16
+ /**
17
+ * ์‹ฑ๊ธ€ํ†ค ์ธ์Šคํ„ด์Šค ์ •๋ฆฌ (๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€)
18
+ */
19
+ static destroyInstance(): void;
20
+ /**
21
+ * ์ธ์Šคํ„ด์Šค ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ
22
+ */
23
+ protected cleanup(): void;
24
+ /**
25
+ * API ์ž๊ฒฉ ์ฆ๋ช…์œผ๋กœ ํด๋ผ์ด์–ธํŠธ ์ดˆ๊ธฐํ™”
26
+ */
27
+ initialize(config: NaverSearchConfig): void;
28
+ /**
29
+ * ๋„ค์ด๋ฒ„ ๊ฒ€์ƒ‰ API ํ˜ธ์ถœ (type๋ณ„๋กœ)
30
+ * @param type ๊ฒ€์ƒ‰ ํƒ€์ž…(์นดํ…Œ๊ณ ๋ฆฌ)
31
+ * @param params ๊ฒ€์ƒ‰ ํŒŒ๋ผ๋ฏธํ„ฐ
32
+ */
33
+ search(type: NaverSearchType, params: SearchArgs): Promise<any>;
34
+ /**
35
+ * ์ „๋ฌธ์ž๋ฃŒ ๊ฒ€์ƒ‰ ๋ฉ”์„œ๋“œ
36
+ */
37
+ searchAcademic(params: NaverDocumentSearchParams): Promise<NaverDocumentSearchResponse>;
38
+ /**
39
+ * ์ง€์—ญ ๊ฒ€์ƒ‰ ๋ฉ”์„œ๋“œ
40
+ */
41
+ searchLocal(params: NaverLocalSearchParams): Promise<NaverLocalSearchResponse>;
42
+ /**
43
+ * ๊ฒ€์ƒ‰์–ด ํŠธ๋ Œ๋“œ ๋ถ„์„ ๋ฉ”์„œ๋“œ
44
+ */
45
+ searchTrend(params: DatalabSearchRequest): Promise<any>;
46
+ /**
47
+ * ์‡ผํ•‘ ์นดํ…Œ๊ณ ๋ฆฌ ํŠธ๋ Œ๋“œ ๋ถ„์„ ๋ฉ”์„œ๋“œ
48
+ */
49
+ datalabShoppingCategory(params: DatalabShoppingCategoryRequest): Promise<DatalabShoppingResponse>;
50
+ /**
51
+ * ์‡ผํ•‘ ๊ธฐ๊ธฐ๋ณ„ ํŠธ๋ Œ๋“œ ๋ถ„์„ ๋ฉ”์„œ๋“œ
52
+ */
53
+ datalabShoppingByDevice(params: DatalabShoppingDeviceRequest): Promise<DatalabShoppingResponse>;
54
+ /**
55
+ * ์‡ผํ•‘ ์„ฑ๋ณ„ ํŠธ๋ Œ๋“œ ๋ถ„์„ ๋ฉ”์„œ๋“œ
56
+ */
57
+ datalabShoppingByGender(params: DatalabShoppingGenderRequest): Promise<DatalabShoppingResponse>;
58
+ /**
59
+ * ์‡ผํ•‘ ์—ฐ๋ น๋ณ„ ํŠธ๋ Œ๋“œ ๋ถ„์„ ๋ฉ”์„œ๋“œ
60
+ */
61
+ datalabShoppingByAge(params: DatalabShoppingAgeRequest): Promise<DatalabShoppingResponse>;
62
+ /**
63
+ * ์‡ผํ•‘ ํ‚ค์›Œ๋“œ ํŠธ๋ Œ๋“œ ๋ถ„์„ ๋ฉ”์„œ๋“œ
64
+ */
65
+ datalabShoppingKeywords(params: DatalabShoppingKeywordsRequest): Promise<DatalabShoppingResponse>;
66
+ /**
67
+ * ์‡ผํ•‘ ํ‚ค์›Œ๋“œ ๊ธฐ๊ธฐ๋ณ„ ํŠธ๋ Œ๋“œ ๋ถ„์„ ๋ฉ”์„œ๋“œ
68
+ */
69
+ datalabShoppingKeywordByDevice(params: DatalabShoppingKeywordRequest): Promise<DatalabShoppingResponse>;
70
+ /**
71
+ * ์‡ผํ•‘ ํ‚ค์›Œ๋“œ ์„ฑ๋ณ„ ํŠธ๋ Œ๋“œ ๋ถ„์„ ๋ฉ”์„œ๋“œ
72
+ */
73
+ datalabShoppingKeywordByGender(params: DatalabShoppingKeywordRequest): Promise<DatalabShoppingResponse>;
74
+ /**
75
+ * ์‡ผํ•‘ ํ‚ค์›Œ๋“œ ์—ฐ๋ น๋ณ„ ํŠธ๋ Œ๋“œ ๋ถ„์„ ๋ฉ”์„œ๋“œ
76
+ */
77
+ datalabShoppingKeywordByAge(params: DatalabShoppingKeywordRequest): Promise<DatalabShoppingResponse>;
78
+ }
@@ -16,6 +16,23 @@ export class NaverSearchClient extends NaverApiCoreClient {
16
16
  }
17
17
  return NaverSearchClient.instance;
18
18
  }
19
+ /**
20
+ * ์‹ฑ๊ธ€ํ†ค ์ธ์Šคํ„ด์Šค ์ •๋ฆฌ (๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€)
21
+ */
22
+ static destroyInstance() {
23
+ if (NaverSearchClient.instance) {
24
+ NaverSearchClient.instance.cleanup();
25
+ NaverSearchClient.instance = null;
26
+ }
27
+ }
28
+ /**
29
+ * ์ธ์Šคํ„ด์Šค ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ
30
+ */
31
+ cleanup() {
32
+ this.config = null;
33
+ // HTTP ์—ฐ๊ฒฐ ์ •๋ฆฌ๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค์—์„œ ์ฒ˜๋ฆฌ
34
+ super.cleanup();
35
+ }
19
36
  /**
20
37
  * API ์ž๊ฒฉ ์ฆ๋ช…์œผ๋กœ ํด๋ผ์ด์–ธํŠธ ์ดˆ๊ธฐํ™”
21
38
  */
@@ -0,0 +1,9 @@
1
+ /**
2
+ * ์บ์‹œ ์ •๋ฆฌ ํ•จ์ˆ˜ (๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€)
3
+ */
4
+ export declare function clearCategoriesCache(): void;
5
+ /**
6
+ * ์นดํ…Œ๊ณ ๋ฆฌ ๊ฒ€์ƒ‰ ํ•ธ๋“ค๋Ÿฌ
7
+ */
8
+ export declare const findCategoryHandler: ({ query, max_results }: any) => Promise<any>;
9
+ export declare const categoryToolHandlers: Record<string, (args: any) => Promise<any>>;
@@ -1,18 +1,26 @@
1
1
  // Import JSON data - bundle-safe approach
2
- import * as fs from 'fs';
3
- import * as path from 'path';
2
+ import { existsSync, readFileSync } from 'fs';
3
+ import { join } from 'path';
4
+ // ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ ์ง€์—ฐ ๋กœ๋”ฉ ์บ์‹œ
5
+ let categoriesCache = null;
4
6
  // Load categories data with fallback paths for different environments
5
7
  function getCategoriesData() {
8
+ // ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์œผ๋ฉด ๋ฐ˜ํ™˜ (๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ)
9
+ if (categoriesCache !== null) {
10
+ return categoriesCache;
11
+ }
6
12
  try {
7
13
  // Try bundled data path first (dist/data)
8
- const bundledPath = path.join(process.cwd(), 'dist', 'data', 'categories.json');
9
- if (fs.existsSync(bundledPath)) {
10
- return JSON.parse(fs.readFileSync(bundledPath, 'utf8'));
14
+ const bundledPath = join(process.cwd(), 'dist', 'data', 'categories.json');
15
+ if (existsSync(bundledPath)) {
16
+ categoriesCache = JSON.parse(readFileSync(bundledPath, 'utf8'));
17
+ return categoriesCache;
11
18
  }
12
19
  // Fallback to source data path
13
- const sourcePath = path.join(process.cwd(), 'data', 'categories.json');
14
- if (fs.existsSync(sourcePath)) {
15
- return JSON.parse(fs.readFileSync(sourcePath, 'utf8'));
20
+ const sourcePath = join(process.cwd(), 'data', 'categories.json');
21
+ if (existsSync(sourcePath)) {
22
+ categoriesCache = JSON.parse(readFileSync(sourcePath, 'utf8'));
23
+ return categoriesCache;
16
24
  }
17
25
  throw new Error('์นดํ…Œ๊ณ ๋ฆฌ ๋ฐ์ดํ„ฐ ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค');
18
26
  }
@@ -21,14 +29,20 @@ function getCategoriesData() {
21
29
  return [];
22
30
  }
23
31
  }
24
- const categoriesData = getCategoriesData();
32
+ /**
33
+ * ์บ์‹œ ์ •๋ฆฌ ํ•จ์ˆ˜ (๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€)
34
+ */
35
+ export function clearCategoriesCache() {
36
+ categoriesCache = null;
37
+ }
25
38
  /**
26
39
  * Load category data from bundled JSON file
27
40
  */
28
41
  async function loadCategoryData() {
29
- // Return the pre-loaded JSON data - no file system access needed
30
- console.error(`Loaded ${categoriesData.length} categories from bundled JSON data`);
31
- return categoriesData;
42
+ // ์ง€์—ฐ ๋กœ๋”ฉ๋œ ์บ์‹œ ๋ฐ์ดํ„ฐ ์‚ฌ์šฉ
43
+ const data = getCategoriesData();
44
+ console.error(`Loaded ${data.length} categories from bundled JSON data`);
45
+ return data;
32
46
  }
33
47
  /**
34
48
  * Smart category search with fuzzy matching and ranking
@@ -0,0 +1,61 @@
1
+ import { DatalabSearch, DatalabShopping, DatalabShoppingDevice, DatalabShoppingGender, DatalabShoppingAge, DatalabShoppingKeywords, DatalabShoppingKeywordDevice, DatalabShoppingKeywordGender, DatalabShoppingKeywordAge } from "../schemas/datalab.schemas.js";
2
+ /**
3
+ * ๋ฐ์ดํ„ฐ๋žฉ ๋„๊ตฌ ํ•ธ๋“ค๋Ÿฌ ๋งต
4
+ * ๊ฐ ๋„๊ตฌ ์ด๋ฆ„์„ ํ‚ค๋กœ, ์‹คํ–‰ํ•  ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ๊ฐ’์œผ๋กœ ๊ฐ€์ง
5
+ * index.ts์—์„œ ๋„๊ตฌ ์‹คํ–‰ ๋ถ„๊ธฐ ์—†์ด ๋ฐ”๋กœ ์‚ฌ์šฉ
6
+ */
7
+ export declare const datalabToolHandlers: Record<string, (args: any) => Promise<any>>;
8
+ /**
9
+ * ๊ฒ€์ƒ‰์–ด ํŠธ๋ Œ๋“œ ํ•ธ๋“ค๋Ÿฌ
10
+ * ๋„ค์ด๋ฒ„ ๋ฐ์ดํ„ฐ๋žฉ ๊ฒ€์ƒ‰์–ด ํŠธ๋ Œ๋“œ ๋ถ„์„ API ํ˜ธ์ถœ
11
+ * @param params DatalabSearch
12
+ */
13
+ export declare function handleSearchTrend(params: DatalabSearch): Promise<any>;
14
+ /**
15
+ * ์‡ผํ•‘ ์นดํ…Œ๊ณ ๋ฆฌ ํŠธ๋ Œ๋“œ ํ•ธ๋“ค๋Ÿฌ
16
+ * ๋„ค์ด๋ฒ„ ๋ฐ์ดํ„ฐ๋žฉ ์‡ผํ•‘ ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ํŠธ๋ Œ๋“œ ๋ถ„์„ API ํ˜ธ์ถœ
17
+ * @param params DatalabShopping
18
+ */
19
+ export declare function handleShoppingCategoryTrend(params: DatalabShopping): Promise<import("../types/datalab.types.js").DatalabShoppingResponse>;
20
+ /**
21
+ * ์‡ผํ•‘ ๊ธฐ๊ธฐ๋ณ„ ํŠธ๋ Œ๋“œ ํ•ธ๋“ค๋Ÿฌ
22
+ * ๋„ค์ด๋ฒ„ ๋ฐ์ดํ„ฐ๋žฉ ์‡ผํ•‘ ๊ธฐ๊ธฐ๋ณ„ ํŠธ๋ Œ๋“œ ๋ถ„์„ API ํ˜ธ์ถœ
23
+ * @param params DatalabShoppingDevice
24
+ */
25
+ export declare function handleShoppingByDeviceTrend(params: DatalabShoppingDevice): Promise<import("../types/datalab.types.js").DatalabShoppingResponse>;
26
+ /**
27
+ * ์‡ผํ•‘ ์„ฑ๋ณ„ ํŠธ๋ Œ๋“œ ํ•ธ๋“ค๋Ÿฌ
28
+ * ๋„ค์ด๋ฒ„ ๋ฐ์ดํ„ฐ๋žฉ ์‡ผํ•‘ ์„ฑ๋ณ„ ํŠธ๋ Œ๋“œ ๋ถ„์„ API ํ˜ธ์ถœ
29
+ * @param params DatalabShoppingGender
30
+ */
31
+ export declare function handleShoppingByGenderTrend(params: DatalabShoppingGender): Promise<import("../types/datalab.types.js").DatalabShoppingResponse>;
32
+ /**
33
+ * ์‡ผํ•‘ ์—ฐ๋ น๋ณ„ ํŠธ๋ Œ๋“œ ํ•ธ๋“ค๋Ÿฌ
34
+ * ๋„ค์ด๋ฒ„ ๋ฐ์ดํ„ฐ๋žฉ ์‡ผํ•‘ ์—ฐ๋ น๋ณ„ ํŠธ๋ Œ๋“œ ๋ถ„์„ API ํ˜ธ์ถœ
35
+ * @param params DatalabShoppingAge
36
+ */
37
+ export declare function handleShoppingByAgeTrend(params: DatalabShoppingAge): Promise<import("../types/datalab.types.js").DatalabShoppingResponse>;
38
+ /**
39
+ * ์‡ผํ•‘ ํ‚ค์›Œ๋“œ ํŠธ๋ Œ๋“œ ํ•ธ๋“ค๋Ÿฌ (๋ณต์ˆ˜ ํ‚ค์›Œ๋“œ ๊ทธ๋ฃน ์ง€์›)
40
+ * ๋„ค์ด๋ฒ„ ๋ฐ์ดํ„ฐ๋žฉ ์‡ผํ•‘ ํ‚ค์›Œ๋“œ ๊ทธ๋ฃน ํŠธ๋ Œ๋“œ ๋ถ„์„ API ํ˜ธ์ถœ
41
+ * @param params DatalabShoppingKeywords
42
+ */
43
+ export declare function handleShoppingKeywordsTrend(params: DatalabShoppingKeywords): Promise<import("../types/datalab.types.js").DatalabShoppingResponse>;
44
+ /**
45
+ * ์‡ผํ•‘ ํ‚ค์›Œ๋“œ ๊ธฐ๊ธฐ๋ณ„ ํŠธ๋ Œ๋“œ ํ•ธ๋“ค๋Ÿฌ
46
+ * ๋„ค์ด๋ฒ„ ๋ฐ์ดํ„ฐ๋žฉ ์‡ผํ•‘ ํ‚ค์›Œ๋“œ ๊ธฐ๊ธฐ๋ณ„ ํŠธ๋ Œ๋“œ ๋ถ„์„ API ํ˜ธ์ถœ
47
+ * @param params DatalabShoppingKeywordDevice
48
+ */
49
+ export declare function handleShoppingKeywordByDeviceTrend(params: DatalabShoppingKeywordDevice): Promise<import("../types/datalab.types.js").DatalabShoppingResponse>;
50
+ /**
51
+ * ์‡ผํ•‘ ํ‚ค์›Œ๋“œ ์„ฑ๋ณ„ ํŠธ๋ Œ๋“œ ํ•ธ๋“ค๋Ÿฌ
52
+ * ๋„ค์ด๋ฒ„ ๋ฐ์ดํ„ฐ๋žฉ ์‡ผํ•‘ ํ‚ค์›Œ๋“œ ์„ฑ๋ณ„ ํŠธ๋ Œ๋“œ ๋ถ„์„ API ํ˜ธ์ถœ
53
+ * @param params DatalabShoppingKeywordGender
54
+ */
55
+ export declare function handleShoppingKeywordByGenderTrend(params: DatalabShoppingKeywordGender): Promise<import("../types/datalab.types.js").DatalabShoppingResponse>;
56
+ /**
57
+ * ์‡ผํ•‘ ํ‚ค์›Œ๋“œ ์—ฐ๋ น๋ณ„ ํŠธ๋ Œ๋“œ ํ•ธ๋“ค๋Ÿฌ
58
+ * ๋„ค์ด๋ฒ„ ๋ฐ์ดํ„ฐ๋žฉ ์‡ผํ•‘ ํ‚ค์›Œ๋“œ ์—ฐ๋ น๋ณ„ ํŠธ๋ Œ๋“œ ๋ถ„์„ API ํ˜ธ์ถœ
59
+ * @param params DatalabShoppingKeywordAge
60
+ */
61
+ export declare function handleShoppingKeywordByAgeTrend(params: DatalabShoppingKeywordAge): Promise<import("../types/datalab.types.js").DatalabShoppingResponse>;