@packative/naver-searchad-mcp 1.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Provotive CO., Ltd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,280 @@
1
+ ```
2
+ _ _ _____ _ _ __ __ _____ _____
3
+ | \ | | / ____| | | | | | \/ |/ ____| __ \
4
+ | \| | __ ___ _____ _ __ | (___ ___ __ _ _ __ ___| |__ __ _ __| | | \ / | | | |__) |
5
+ | . ` |/ _` \ \ / / _ \ '__| \___ \ / _ \/ _` | '__/ __| '_ \ / _` |/ _` | | |\/| | | | ___/
6
+ | |\ | (_| |\ V / __/ | ____) | __/ (_| | | | (__| | | | (_| | (_| | | | | | |____| |
7
+ |_| \_|\__,_| \_/ \___|_| |_____/ \___|\__,_|_| \___|_| |_|\__,_|\__,_| |_| |_|\_____|_|
8
+ ```
9
+
10
+ # @packative/naver-searchad-mcp
11
+
12
+ An MCP (Model Context Protocol) server for the Naver SearchAd API. Manage campaigns, ad groups, keywords, and retrieve performance statistics directly from Claude Desktop or any MCP-compatible client.
13
+
14
+ ## Credits
15
+
16
+ This project is a fork of [ND-SPACE/naver-searchad-mcp](https://github.com/ND-SPACE/naver-searchad-mcp), extended with additional features and improvements by [Packative](https://packative.com).
17
+
18
+ ## Features
19
+
20
+ - **Campaign Management**: List, create, and delete campaigns
21
+ - **Ad Group Management**: List, get details, and create ad groups
22
+ - **Keyword Management**: List and add keywords to ad groups
23
+ - **Performance Statistics**: Retrieve detailed stats with flexible date ranges and breakdowns
24
+ - **Active Campaign Filtering**: Automatically filters to show only active (ELIGIBLE) campaigns
25
+ - **TypeScript**: Fully typed for better developer experience
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ npm install -g @packative/naver-searchad-mcp
31
+ ```
32
+
33
+ Or with pnpm:
34
+
35
+ ```bash
36
+ pnpm add -g @packative/naver-searchad-mcp
37
+ ```
38
+
39
+ ## Configuration
40
+
41
+ ### Environment Variables
42
+
43
+ The server requires the following environment variables:
44
+
45
+ | Variable | Description |
46
+ |----------|-------------|
47
+ | `NAVER_API_KEY` | Your Naver SearchAd API key |
48
+ | `NAVER_SIGN_KEY` | Your Naver SearchAd secret key for signing requests |
49
+ | `NAVER_CUSTOMER_ID` | Your Naver advertiser customer ID |
50
+
51
+ ### Claude Desktop Setup
52
+
53
+ Add the following to your Claude Desktop configuration file:
54
+
55
+ **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
56
+ **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
57
+
58
+ ```json
59
+ {
60
+ "mcpServers": {
61
+ "naver-searchad": {
62
+ "command": "npx",
63
+ "args": ["-y", "@packative/naver-searchad-mcp"],
64
+ "env": {
65
+ "NAVER_API_KEY": "your-api-key",
66
+ "NAVER_SIGN_KEY": "your-secret-key",
67
+ "NAVER_CUSTOMER_ID": "your-customer-id"
68
+ }
69
+ }
70
+ }
71
+ }
72
+ ```
73
+
74
+ ### Claude Code Setup
75
+
76
+ Add to your Claude Code settings:
77
+
78
+ ```json
79
+ {
80
+ "mcpServers": {
81
+ "naver-searchad": {
82
+ "command": "npx",
83
+ "args": ["-y", "@packative/naver-searchad-mcp"],
84
+ "env": {
85
+ "NAVER_API_KEY": "your-api-key",
86
+ "NAVER_SIGN_KEY": "your-secret-key",
87
+ "NAVER_CUSTOMER_ID": "your-customer-id"
88
+ }
89
+ }
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## Available Tools
95
+
96
+ ### Campaign Tools
97
+
98
+ #### `list_campaigns`
99
+ List all Naver SearchAd campaigns.
100
+
101
+ #### `create_campaign`
102
+ Create a new campaign.
103
+
104
+ | Parameter | Type | Required | Description |
105
+ |-----------|------|----------|-------------|
106
+ | `name` | string | Yes | Campaign name |
107
+ | `campaignTp` | string | Yes | Campaign type (e.g., `WEB_SITE`, `SHOPPING`) |
108
+ | `customerId` | string | No | Customer ID |
109
+ | `dailyBudget` | number | No | Daily budget in KRW |
110
+ | `deliveryMethod` | string | No | `STANDARD` or `ACCELERATED` |
111
+
112
+ #### `delete_campaign`
113
+ Delete a campaign.
114
+
115
+ | Parameter | Type | Required | Description |
116
+ |-----------|------|----------|-------------|
117
+ | `campaignId` | string | Yes | Campaign ID to delete |
118
+
119
+ ### Ad Group Tools
120
+
121
+ #### `list_adgroups`
122
+ List all ad groups, optionally filtered by campaign.
123
+
124
+ | Parameter | Type | Required | Description |
125
+ |-----------|------|----------|-------------|
126
+ | `campaignId` | string | No | Filter by campaign ID |
127
+
128
+ #### `get_adgroup`
129
+ Get details of a specific ad group.
130
+
131
+ | Parameter | Type | Required | Description |
132
+ |-----------|------|----------|-------------|
133
+ | `adgroupId` | string | Yes | Ad group ID |
134
+
135
+ #### `create_adgroup`
136
+ Create a new ad group.
137
+
138
+ | Parameter | Type | Required | Description |
139
+ |-----------|------|----------|-------------|
140
+ | `nccCampaignId` | string | Yes | Parent campaign ID |
141
+ | `name` | string | Yes | Ad group name |
142
+ | `pcChannelId` | string | No | PC channel ID |
143
+ | `mobileChannelId` | string | No | Mobile channel ID |
144
+ | `bidAmt` | number | No | Bid amount in KRW |
145
+
146
+ ### Keyword Tools
147
+
148
+ #### `list_keywords`
149
+ List all keywords in an ad group.
150
+
151
+ | Parameter | Type | Required | Description |
152
+ |-----------|------|----------|-------------|
153
+ | `adgroupId` | string | Yes | Ad group ID |
154
+
155
+ #### `create_keyword`
156
+ Add a keyword to an ad group.
157
+
158
+ | Parameter | Type | Required | Description |
159
+ |-----------|------|----------|-------------|
160
+ | `adgroupId` | string | Yes | Ad group ID |
161
+ | `keyword` | string | Yes | Keyword text |
162
+ | `bidAmt` | number | No | Bid amount in KRW |
163
+
164
+ ### Statistics Tools
165
+
166
+ #### `get_stats`
167
+ Get performance statistics for campaigns, ad groups, or keywords.
168
+
169
+ | Parameter | Type | Required | Description |
170
+ |-----------|------|----------|-------------|
171
+ | `id` | string | No | Single ID to query |
172
+ | `ids` | array | No | Multiple IDs to query |
173
+ | `fields` | array | No | Metrics to retrieve (default: `impCnt`, `clkCnt`, `salesAmt`, `ctr`, `cpc`, `ccnt`) |
174
+ | `datePreset` | string | No | `today`, `yesterday`, `last7days`, `last30days`, `lastweek`, `lastmonth`, `lastquarter` |
175
+ | `timeRange` | object | No | Custom date range with `since` and `until` (YYYY-MM-DD) |
176
+ | `timeIncrement` | string | No | `1` (daily) or `allDays` (summary) |
177
+ | `breakdown` | string | No | `pcMblTp` (device), `dayw` (day of week), `hh24` (hour), `regnNo` (region) |
178
+
179
+ **Available metrics:**
180
+ - `impCnt` - Impressions
181
+ - `clkCnt` - Clicks
182
+ - `salesAmt` - Cost/Spend
183
+ - `ctr` - Click-through rate
184
+ - `cpc` - Cost per click
185
+ - `ccnt` - Conversions
186
+ - `crto` - Conversion rate
187
+ - `convAmt` - Conversion value
188
+ - `ror` - Return on ad spend
189
+ - `cpConv` - Cost per conversion
190
+ - `avgRnk` - Average rank
191
+
192
+ #### `get_campaign_stats`
193
+ Get performance statistics for all active campaigns.
194
+
195
+ | Parameter | Type | Required | Description |
196
+ |-----------|------|----------|-------------|
197
+ | `startDate` | string | No | Start date (YYYY-MM-DD) |
198
+ | `endDate` | string | No | End date (YYYY-MM-DD) |
199
+ | `datePreset` | string | No | Use preset instead of custom dates |
200
+
201
+ ## Usage Examples
202
+
203
+ ### List all campaigns
204
+ ```
205
+ "Show me all my Naver SearchAd campaigns"
206
+ ```
207
+
208
+ ### Get campaign performance
209
+ ```
210
+ "What's the performance of my Naver campaigns for the last 30 days?"
211
+ ```
212
+
213
+ ### Create a new campaign
214
+ ```
215
+ "Create a new Naver SearchAd campaign called 'Summer Sale' with type WEB_SITE"
216
+ ```
217
+
218
+ ### Get keyword statistics
219
+ ```
220
+ "Show me the click-through rate for my keywords in the last week"
221
+ ```
222
+
223
+ ## Getting API Credentials
224
+
225
+ 1. Log in to [Naver SearchAd](https://searchad.naver.com/)
226
+ 2. Go to Tools > API Management
227
+ 3. Create a new API key
228
+ 4. Note your API Key, Secret Key, and Customer ID
229
+
230
+ For detailed API documentation, see the [Official Naver SearchAd API Documentation](https://naver.github.io/searchad-apidoc/#/guides).
231
+
232
+ ## Development
233
+
234
+ ```bash
235
+ # Install dependencies
236
+ pnpm install
237
+
238
+ # Run tests
239
+ pnpm test
240
+
241
+ # Run tests in watch mode
242
+ pnpm test:watch
243
+
244
+ # Run tests with coverage
245
+ pnpm test:coverage
246
+
247
+ # Type check
248
+ pnpm typecheck
249
+
250
+ # Build
251
+ pnpm build
252
+ ```
253
+
254
+ ## Requirements
255
+
256
+ - Node.js 18 or higher
257
+ - Naver SearchAd API credentials
258
+
259
+ ## License
260
+
261
+ MIT License - see [LICENSE](LICENSE) for details.
262
+
263
+ ## Contributing
264
+
265
+ We use [Conventional Commits](https://www.conventionalcommits.org/) for automatic versioning and changelog generation.
266
+
267
+ - **`development`** branch for ongoing work
268
+ - **`master`** branch is protected - merging triggers automatic releases
269
+
270
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
271
+
272
+ Issues and pull requests are welcome on [GitHub](https://github.com/packative/naver-searchad-mcp).
273
+
274
+ ---
275
+
276
+ ### About Packative
277
+
278
+ [Packative](https://packative.com) is a Korean packaging e-commerce platform that helps businesses find and order custom packaging solutions. We build tools to streamline our marketing operations and share them with the community.
279
+
280
+ This MCP server is part of our marketing automation toolkit, enabling AI-assisted management of Naver SearchAd campaigns.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,435 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
5
+ import { fetchWithAuth } from "./utils/fetchWithAuth.js";
6
+ const server = new Server({
7
+ name: "@packative/naver-searchad-mcp",
8
+ version: "1.0.0",
9
+ }, {
10
+ capabilities: {
11
+ tools: {},
12
+ },
13
+ });
14
+ // Define all tools
15
+ const tools = [
16
+ {
17
+ name: "list_campaigns",
18
+ description: "List all Naver SearchAd campaigns",
19
+ inputSchema: {
20
+ type: "object",
21
+ properties: {},
22
+ required: [],
23
+ },
24
+ },
25
+ {
26
+ name: "create_campaign",
27
+ description: "Create a new Naver SearchAd campaign",
28
+ inputSchema: {
29
+ type: "object",
30
+ properties: {
31
+ name: {
32
+ type: "string",
33
+ description: "Campaign name",
34
+ },
35
+ campaignTp: {
36
+ type: "string",
37
+ description: "Campaign type (e.g., WEB_SITE, SHOPPING)",
38
+ },
39
+ customerId: {
40
+ type: "string",
41
+ description: "Customer ID",
42
+ },
43
+ dailyBudget: {
44
+ type: "number",
45
+ description: "Daily budget in KRW",
46
+ },
47
+ deliveryMethod: {
48
+ type: "string",
49
+ description: "Delivery method (STANDARD or ACCELERATED)",
50
+ },
51
+ },
52
+ required: ["name", "campaignTp"],
53
+ },
54
+ },
55
+ {
56
+ name: "delete_campaign",
57
+ description: "Delete a Naver SearchAd campaign",
58
+ inputSchema: {
59
+ type: "object",
60
+ properties: {
61
+ campaignId: {
62
+ type: "string",
63
+ description: "Campaign ID to delete",
64
+ },
65
+ },
66
+ required: ["campaignId"],
67
+ },
68
+ },
69
+ {
70
+ name: "list_adgroups",
71
+ description: "List all ad groups, optionally filtered by campaign",
72
+ inputSchema: {
73
+ type: "object",
74
+ properties: {
75
+ campaignId: {
76
+ type: "string",
77
+ description: "Optional: Campaign ID to filter ad groups",
78
+ },
79
+ },
80
+ required: [],
81
+ },
82
+ },
83
+ {
84
+ name: "get_adgroup",
85
+ description: "Get details of a specific ad group",
86
+ inputSchema: {
87
+ type: "object",
88
+ properties: {
89
+ adgroupId: {
90
+ type: "string",
91
+ description: "Ad group ID",
92
+ },
93
+ },
94
+ required: ["adgroupId"],
95
+ },
96
+ },
97
+ {
98
+ name: "create_adgroup",
99
+ description: "Create a new ad group within a campaign",
100
+ inputSchema: {
101
+ type: "object",
102
+ properties: {
103
+ nccCampaignId: {
104
+ type: "string",
105
+ description: "Campaign ID to create ad group in",
106
+ },
107
+ name: {
108
+ type: "string",
109
+ description: "Ad group name",
110
+ },
111
+ pcChannelId: {
112
+ type: "string",
113
+ description: "PC channel ID",
114
+ },
115
+ mobileChannelId: {
116
+ type: "string",
117
+ description: "Mobile channel ID",
118
+ },
119
+ bidAmt: {
120
+ type: "number",
121
+ description: "Bid amount in KRW",
122
+ },
123
+ },
124
+ required: ["nccCampaignId", "name"],
125
+ },
126
+ },
127
+ {
128
+ name: "list_keywords",
129
+ description: "List all keywords in an ad group",
130
+ inputSchema: {
131
+ type: "object",
132
+ properties: {
133
+ adgroupId: {
134
+ type: "string",
135
+ description: "Ad group ID",
136
+ },
137
+ },
138
+ required: ["adgroupId"],
139
+ },
140
+ },
141
+ {
142
+ name: "create_keyword",
143
+ description: "Add a keyword to an ad group",
144
+ inputSchema: {
145
+ type: "object",
146
+ properties: {
147
+ adgroupId: {
148
+ type: "string",
149
+ description: "Ad group ID",
150
+ },
151
+ keyword: {
152
+ type: "string",
153
+ description: "Keyword text",
154
+ },
155
+ bidAmt: {
156
+ type: "number",
157
+ description: "Bid amount in KRW",
158
+ },
159
+ },
160
+ required: ["adgroupId", "keyword"],
161
+ },
162
+ },
163
+ {
164
+ name: "get_stats",
165
+ description: "Get performance statistics for campaigns, ad groups, or keywords. Returns impressions, clicks, cost, conversions, etc.",
166
+ inputSchema: {
167
+ type: "object",
168
+ properties: {
169
+ id: {
170
+ type: "string",
171
+ description: "Single ID (campaign, adgroup, or keyword ID)",
172
+ },
173
+ ids: {
174
+ type: "array",
175
+ items: { type: "string" },
176
+ description: "Multiple IDs to query at once",
177
+ },
178
+ fields: {
179
+ type: "array",
180
+ items: { type: "string" },
181
+ description: "Metrics to retrieve: impCnt, clkCnt, salesAmt, ctr, cpc, ccnt, crto, convAmt, ror, cpConv, avgRnk",
182
+ },
183
+ datePreset: {
184
+ type: "string",
185
+ description: "Predefined date range: today, yesterday, last7days, last30days, lastweek, lastmonth, lastquarter",
186
+ },
187
+ timeRange: {
188
+ type: "object",
189
+ properties: {
190
+ since: { type: "string", description: "Start date (YYYY-MM-DD)" },
191
+ until: { type: "string", description: "End date (YYYY-MM-DD)" },
192
+ },
193
+ description: "Custom date range (use instead of datePreset)",
194
+ },
195
+ timeIncrement: {
196
+ type: "string",
197
+ description: "Time granularity: 1 (daily) or allDays (summary)",
198
+ },
199
+ breakdown: {
200
+ type: "string",
201
+ description: "Breakdown dimension: pcMblTp (device), dayw (day of week), hh24 (hour), regnNo (region)",
202
+ },
203
+ },
204
+ required: [],
205
+ },
206
+ },
207
+ {
208
+ name: "get_campaign_stats",
209
+ description: "Get performance statistics for all active campaigns",
210
+ inputSchema: {
211
+ type: "object",
212
+ properties: {
213
+ startDate: {
214
+ type: "string",
215
+ description: "Start date (YYYY-MM-DD)",
216
+ },
217
+ endDate: {
218
+ type: "string",
219
+ description: "End date (YYYY-MM-DD)",
220
+ },
221
+ datePreset: {
222
+ type: "string",
223
+ description: "Or use preset: today, yesterday, last7days, last30days, lastweek, lastmonth, lastquarter",
224
+ },
225
+ },
226
+ required: [],
227
+ },
228
+ },
229
+ ];
230
+ // Handle list tools request
231
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
232
+ return { tools };
233
+ });
234
+ // Handle tool calls
235
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
236
+ const { name, arguments: args = {} } = request.params;
237
+ try {
238
+ let result;
239
+ switch (name) {
240
+ case "list_campaigns": {
241
+ const response = await fetchWithAuth("/ncc/campaigns");
242
+ result = response.data;
243
+ break;
244
+ }
245
+ case "create_campaign": {
246
+ const typedArgs = args;
247
+ const campaign = {
248
+ name: typedArgs.name,
249
+ campaignTp: typedArgs.campaignTp,
250
+ customerId: typedArgs.customerId,
251
+ dailyBudget: typedArgs.dailyBudget,
252
+ deliveryMethod: typedArgs.deliveryMethod,
253
+ };
254
+ const response = await fetchWithAuth("/ncc/campaigns", "POST", campaign);
255
+ result = response.data;
256
+ break;
257
+ }
258
+ case "delete_campaign": {
259
+ const typedArgs = args;
260
+ const response = await fetchWithAuth(`/ncc/campaigns/${typedArgs.campaignId}`, "DELETE");
261
+ result = response.data;
262
+ break;
263
+ }
264
+ case "list_adgroups": {
265
+ const typedArgs = args;
266
+ const endpoint = typedArgs.campaignId
267
+ ? `/ncc/adgroups?nccCampaignId=${typedArgs.campaignId}`
268
+ : `/ncc/adgroups`;
269
+ const response = await fetchWithAuth(endpoint);
270
+ result = response.data;
271
+ break;
272
+ }
273
+ case "get_adgroup": {
274
+ const typedArgs = args;
275
+ const response = await fetchWithAuth(`/ncc/adgroups/${typedArgs.adgroupId}`);
276
+ result = response.data;
277
+ break;
278
+ }
279
+ case "create_adgroup": {
280
+ const typedArgs = args;
281
+ const adgroup = {
282
+ nccCampaignId: typedArgs.nccCampaignId,
283
+ name: typedArgs.name,
284
+ pcChannelId: typedArgs.pcChannelId,
285
+ mobileChannelId: typedArgs.mobileChannelId,
286
+ bidAmt: typedArgs.bidAmt,
287
+ };
288
+ const response = await fetchWithAuth("/ncc/adgroups", "POST", adgroup);
289
+ result = response.data;
290
+ break;
291
+ }
292
+ case "list_keywords": {
293
+ const typedArgs = args;
294
+ const response = await fetchWithAuth(`/ncc/keywords?nccAdgroupId=${typedArgs.adgroupId}`);
295
+ result = response.data;
296
+ break;
297
+ }
298
+ case "create_keyword": {
299
+ const typedArgs = args;
300
+ const keyword = {
301
+ keyword: typedArgs.keyword,
302
+ bidAmt: typedArgs.bidAmt,
303
+ };
304
+ const response = await fetchWithAuth(`/ncc/keywords?nccAdgroupId=${typedArgs.adgroupId}`, "POST", keyword);
305
+ result = response.data;
306
+ break;
307
+ }
308
+ case "get_stats": {
309
+ const typedArgs = args;
310
+ const params = new URLSearchParams();
311
+ if (typedArgs.id) {
312
+ params.append("id", typedArgs.id);
313
+ }
314
+ if (typedArgs.ids && typedArgs.ids.length > 0) {
315
+ params.append("ids", JSON.stringify(typedArgs.ids));
316
+ }
317
+ // Fields - default to common metrics
318
+ const fields = typedArgs.fields || [
319
+ "impCnt",
320
+ "clkCnt",
321
+ "salesAmt",
322
+ "ctr",
323
+ "cpc",
324
+ "ccnt",
325
+ ];
326
+ params.append("fields", JSON.stringify(fields));
327
+ // Date range
328
+ if (typedArgs.timeRange) {
329
+ params.append("timeRange", JSON.stringify(typedArgs.timeRange));
330
+ }
331
+ else if (typedArgs.datePreset) {
332
+ params.append("datePreset", typedArgs.datePreset);
333
+ }
334
+ else {
335
+ params.append("datePreset", "last30days");
336
+ }
337
+ // Time increment
338
+ params.append("timeIncrement", typedArgs.timeIncrement || "allDays");
339
+ // Breakdown
340
+ if (typedArgs.breakdown) {
341
+ params.append("breakdown", typedArgs.breakdown);
342
+ }
343
+ const response = await fetchWithAuth(`/stats?${params.toString()}`);
344
+ result = response.data;
345
+ break;
346
+ }
347
+ case "get_campaign_stats": {
348
+ const typedArgs = args;
349
+ // First get all campaigns
350
+ const campaignsResponse = await fetchWithAuth("/ncc/campaigns");
351
+ const campaigns = campaignsResponse.data;
352
+ // Filter to ELIGIBLE campaigns only
353
+ const activeCampaigns = campaigns.filter((c) => c.status === "ELIGIBLE");
354
+ const campaignIds = activeCampaigns.map((c) => c.nccCampaignId);
355
+ if (campaignIds.length === 0) {
356
+ result = { message: "No active campaigns found", campaigns: [] };
357
+ break;
358
+ }
359
+ // Build stats query
360
+ const params = new URLSearchParams();
361
+ params.append("ids", JSON.stringify(campaignIds));
362
+ params.append("fields", JSON.stringify([
363
+ "impCnt",
364
+ "clkCnt",
365
+ "salesAmt",
366
+ "ctr",
367
+ "cpc",
368
+ "ccnt",
369
+ "crto",
370
+ "convAmt",
371
+ ]));
372
+ if (typedArgs.startDate && typedArgs.endDate) {
373
+ params.append("timeRange", JSON.stringify({
374
+ since: typedArgs.startDate,
375
+ until: typedArgs.endDate,
376
+ }));
377
+ }
378
+ else if (typedArgs.datePreset) {
379
+ params.append("datePreset", typedArgs.datePreset);
380
+ }
381
+ else {
382
+ params.append("datePreset", "last30days");
383
+ }
384
+ params.append("timeIncrement", "allDays");
385
+ const statsResponse = await fetchWithAuth(`/stats?${params.toString()}`);
386
+ // Merge campaign info with stats
387
+ const statsMap = {};
388
+ if (Array.isArray(statsResponse.data)) {
389
+ statsResponse.data.forEach((stat) => {
390
+ statsMap[stat.id] = stat;
391
+ });
392
+ }
393
+ result = activeCampaigns.map((campaign) => ({
394
+ ...campaign,
395
+ stats: statsMap[campaign.nccCampaignId] || null,
396
+ }));
397
+ break;
398
+ }
399
+ default:
400
+ throw new Error(`Unknown tool: ${name}`);
401
+ }
402
+ return {
403
+ content: [
404
+ {
405
+ type: "text",
406
+ text: JSON.stringify(result, null, 2),
407
+ },
408
+ ],
409
+ };
410
+ }
411
+ catch (error) {
412
+ const err = error;
413
+ const errorMessage = err.response?.data?.message || err.message;
414
+ return {
415
+ content: [
416
+ {
417
+ type: "text",
418
+ text: `Error: ${errorMessage}`,
419
+ },
420
+ ],
421
+ isError: true,
422
+ };
423
+ }
424
+ });
425
+ // Start the server
426
+ async function main() {
427
+ const transport = new StdioServerTransport();
428
+ await server.connect(transport);
429
+ console.error("Naver SearchAd MCP server running on stdio");
430
+ }
431
+ main().catch((error) => {
432
+ console.error("Server error:", error);
433
+ process.exit(1);
434
+ });
435
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ import type { AxiosResponse } from "axios";
2
+ export interface Campaign {
3
+ nccCampaignId: string;
4
+ customerId: number;
5
+ name: string;
6
+ campaignTp: string;
7
+ deliveryMethod: string;
8
+ trackingMode: string;
9
+ dailyBudget: number;
10
+ useDailyBudget: boolean;
11
+ status: "ELIGIBLE" | "PAUSED" | "SUSPENDED" | "DELETED";
12
+ statusReason: string;
13
+ regTm: string;
14
+ editTm: string;
15
+ }
16
+ export interface AdGroup {
17
+ nccAdgroupId: string;
18
+ nccCampaignId: string;
19
+ customerId: number;
20
+ name: string;
21
+ pcChannelId?: string;
22
+ mobileChannelId?: string;
23
+ bidAmt: number;
24
+ status: string;
25
+ regTm: string;
26
+ editTm: string;
27
+ }
28
+ export interface Keyword {
29
+ nccKeywordId: string;
30
+ nccAdgroupId: string;
31
+ customerId: number;
32
+ keyword: string;
33
+ bidAmt: number;
34
+ status: string;
35
+ regTm: string;
36
+ editTm: string;
37
+ }
38
+ export interface Stats {
39
+ id: string;
40
+ impCnt?: number;
41
+ clkCnt?: number;
42
+ salesAmt?: number;
43
+ ctr?: number;
44
+ cpc?: number;
45
+ ccnt?: number;
46
+ crto?: number;
47
+ convAmt?: number;
48
+ ror?: number;
49
+ cpConv?: number;
50
+ avgRnk?: number;
51
+ }
52
+ export interface CampaignWithStats extends Campaign {
53
+ stats: Stats | null;
54
+ }
55
+ export interface CreateCampaignArgs {
56
+ name: string;
57
+ campaignTp: string;
58
+ customerId?: string;
59
+ dailyBudget?: number;
60
+ deliveryMethod?: string;
61
+ }
62
+ export interface DeleteCampaignArgs {
63
+ campaignId: string;
64
+ }
65
+ export interface ListAdgroupsArgs {
66
+ campaignId?: string;
67
+ }
68
+ export interface GetAdgroupArgs {
69
+ adgroupId: string;
70
+ }
71
+ export interface CreateAdgroupArgs {
72
+ nccCampaignId: string;
73
+ name: string;
74
+ pcChannelId?: string;
75
+ mobileChannelId?: string;
76
+ bidAmt?: number;
77
+ }
78
+ export interface ListKeywordsArgs {
79
+ adgroupId: string;
80
+ }
81
+ export interface CreateKeywordArgs {
82
+ adgroupId: string;
83
+ keyword: string;
84
+ bidAmt?: number;
85
+ }
86
+ export interface TimeRange {
87
+ since: string;
88
+ until: string;
89
+ }
90
+ export interface GetStatsArgs {
91
+ id?: string;
92
+ ids?: string[];
93
+ fields?: string[];
94
+ datePreset?: string;
95
+ timeRange?: TimeRange;
96
+ timeIncrement?: string;
97
+ breakdown?: string;
98
+ }
99
+ export interface GetCampaignStatsArgs {
100
+ startDate?: string;
101
+ endDate?: string;
102
+ datePreset?: string;
103
+ }
104
+ export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
105
+ export type ApiResponse<T = unknown> = AxiosResponse<T>;
106
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { HttpMethod, ApiResponse } from "../types.js";
2
+ /**
3
+ * Make authenticated request to Naver SearchAd API
4
+ */
5
+ export declare function fetchWithAuth<T = unknown>(path: string, method?: HttpMethod, data?: unknown): Promise<ApiResponse<T>>;
6
+ //# sourceMappingURL=fetchWithAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchWithAuth.d.ts","sourceRoot":"","sources":["../../src/utils/fetchWithAuth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAmB3D;;GAEG;AACH,wBAAsB,aAAa,CAAC,CAAC,GAAG,OAAO,EAC7C,IAAI,EAAE,MAAM,EACZ,MAAM,GAAE,UAAkB,EAC1B,IAAI,GAAE,OAAc,GACnB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CA0BzB"}
@@ -0,0 +1,38 @@
1
+ import axios from "axios";
2
+ import crypto from "crypto";
3
+ const NAVER_API_BASE_URL = "https://api.naver.com";
4
+ /**
5
+ * Generate HMAC-SHA256 signature for Naver API authentication
6
+ */
7
+ function generateSignature(timestamp, method, path, secretKey) {
8
+ const message = `${timestamp}.${method}.${path}`;
9
+ const hmac = crypto.createHmac("sha256", secretKey);
10
+ hmac.update(message);
11
+ return hmac.digest("base64");
12
+ }
13
+ /**
14
+ * Make authenticated request to Naver SearchAd API
15
+ */
16
+ export async function fetchWithAuth(path, method = "GET", data = null) {
17
+ const apiKey = process.env.NAVER_API_KEY;
18
+ const secretKey = process.env.NAVER_SIGN_KEY;
19
+ const customerId = process.env.NAVER_CUSTOMER_ID;
20
+ if (!apiKey || !secretKey || !customerId) {
21
+ throw new Error(`Missing environment variables: NAVER_API_KEY=${!!apiKey}, NAVER_SIGN_KEY=${!!secretKey}, NAVER_CUSTOMER_ID=${!!customerId}`);
22
+ }
23
+ const timestamp = Date.now().toString();
24
+ const signature = generateSignature(timestamp, method, path, secretKey);
25
+ return axios({
26
+ method,
27
+ url: `${NAVER_API_BASE_URL}${path}`,
28
+ headers: {
29
+ "X-API-KEY": apiKey,
30
+ "X-Customer": customerId,
31
+ "X-Timestamp": timestamp,
32
+ "X-Signature": signature,
33
+ "Content-Type": "application/json",
34
+ },
35
+ data,
36
+ });
37
+ }
38
+ //# sourceMappingURL=fetchWithAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchWithAuth.js","sourceRoot":"","sources":["../../src/utils/fetchWithAuth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,MAAM,kBAAkB,GAAG,uBAAuB,CAAC;AAEnD;;GAEG;AACH,SAAS,iBAAiB,CACxB,SAAiB,EACjB,MAAc,EACd,IAAY,EACZ,SAAiB;IAEjB,MAAM,OAAO,GAAG,GAAG,SAAS,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAY,EACZ,SAAqB,KAAK,EAC1B,OAAgB,IAAI;IAEpB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IACzC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAEjD,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CACb,gDAAgD,CAAC,CAAC,MAAM,oBAAoB,CAAC,CAAC,SAAS,uBAAuB,CAAC,CAAC,UAAU,EAAE,CAC7H,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IACxC,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IAExE,OAAO,KAAK,CAAI;QACd,MAAM;QACN,GAAG,EAAE,GAAG,kBAAkB,GAAG,IAAI,EAAE;QACnC,OAAO,EAAE;YACP,WAAW,EAAE,MAAM;YACnB,YAAY,EAAE,UAAU;YACxB,aAAa,EAAE,SAAS;YACxB,aAAa,EAAE,SAAS;YACxB,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI;KACL,CAAC,CAAC;AACL,CAAC"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@packative/naver-searchad-mcp",
3
+ "version": "1.2.0",
4
+ "type": "module",
5
+ "description": "MCP server for Naver SearchAd API - manage campaigns, ad groups, keywords, and retrieve performance statistics",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "naver-searchad-mcp": "dist/index.js"
10
+ },
11
+ "files": [
12
+ "dist/"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "dev": "tsc --watch",
17
+ "test": "vitest run",
18
+ "test:watch": "vitest",
19
+ "test:coverage": "vitest run --coverage",
20
+ "prepublishOnly": "pnpm run build",
21
+ "typecheck": "tsc --noEmit"
22
+ },
23
+ "keywords": [
24
+ "claude",
25
+ "mcp",
26
+ "model-context-protocol",
27
+ "naver",
28
+ "searchad",
29
+ "advertising",
30
+ "ppc",
31
+ "korea"
32
+ ],
33
+ "author": "Provotive Co., Ltd",
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/packative/naver-searchad-mcp"
38
+ },
39
+ "homepage": "https://github.com/packative/naver-searchad-mcp#readme",
40
+ "bugs": {
41
+ "url": "https://github.com/packative/naver-searchad-mcp/issues"
42
+ },
43
+ "engines": {
44
+ "node": ">=18"
45
+ },
46
+ "dependencies": {
47
+ "@modelcontextprotocol/sdk": "^1.25.2",
48
+ "axios": "^1.7.0"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^22.0.0",
52
+ "@vitest/coverage-v8": "^2.1.0",
53
+ "typescript": "^5.7.0",
54
+ "vitest": "^2.1.0"
55
+ }
56
+ }