nworks 1.1.2 → 1.2.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.
package/dist/index.js CHANGED
@@ -470,7 +470,11 @@ Opening browser for NAVER WORKS login...`);
470
470
  `);
471
471
  const { exec } = await import("child_process");
472
472
  const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
473
- exec(`${openCmd} "${authorizeUrl}"`);
473
+ if (process.platform === "win32") {
474
+ exec(`start "" "${authorizeUrl}"`);
475
+ } else {
476
+ exec(`${openCmd} "${authorizeUrl}"`);
477
+ }
474
478
  const tokenData = await startUserOAuthFlow(scope, profile);
475
479
  await saveUserToken(tokenData, profile);
476
480
  output(
@@ -569,7 +573,7 @@ var ERROR_HINTS_MCP = {
569
573
  FORBIDDEN: "\uAD8C\uD55C\uC774 \uBD80\uC871\uD569\uB2C8\uB2E4. Developer Console\uC5D0\uC11C OAuth Scope\uB97C \uD655\uC778\uD558\uC138\uC694.",
570
574
  ACCESS_DENIED: "\uC811\uADFC\uC774 \uAC70\uBD80\uB410\uC2B5\uB2C8\uB2E4. Admin\uC5D0\uC11C Bot\uC744 \uCD94\uAC00\uD588\uB294\uC9C0 \uD655\uC778\uD558\uC138\uC694.",
571
575
  SERVICE_ACCOUNT_NOT_ALLOWED: "\uC11C\uBE44\uC2A4 \uACC4\uC815\uC73C\uB85C\uB294 \uC774 API\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. nworks_login_user tool\uB85C User OAuth \uB85C\uADF8\uC778\uC744 \uBA3C\uC800 \uD574\uC8FC\uC138\uC694.",
572
- UNAUTHORIZED: "\uC778\uC99D\uC774 \uB9CC\uB8CC\uB410\uC2B5\uB2C8\uB2E4. nworks_setup tool\uB85C \uC7AC\uC124\uC815\uD558\uC138\uC694."
576
+ UNAUTHORIZED: "\uC778\uC99D\uC774 \uB9CC\uB8CC\uB410\uC2B5\uB2C8\uB2E4. nworks_login_user tool\uB85C \uB2E4\uC2DC \uBE0C\uB77C\uC6B0\uC800 \uB85C\uADF8\uC778\uD558\uC138\uC694. \uADF8\uB798\uB3C4 \uC548 \uB418\uBA74 nworks_setup tool\uB85C \uC7AC\uC124\uC815 \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694."
573
577
  };
574
578
  function cliErrorHint(err, area) {
575
579
  if (err instanceof ApiError) {
@@ -601,7 +605,7 @@ function mcpErrorHint(err, area) {
601
605
  if (err instanceof AuthError) {
602
606
  return `Error: ${err.message}
603
607
 
604
- [\uC548\uB0B4] \uC778\uC99D \uC815\uBCF4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. nworks_setup tool\uB85C Client ID/Secret\uC744 \uBA3C\uC800 \uC124\uC815\uD574\uC8FC\uC138\uC694.`;
608
+ [\uC548\uB0B4] \uC778\uC99D \uC815\uBCF4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. nworks_setup tool\uC744 \uBA3C\uC800 \uD638\uCD9C\uD558\uC138\uC694 (Client ID \uD544\uC694, Client Secret\uC740 \uD658\uACBD\uBCC0\uC218 NWORKS_CLIENT_SECRET\uC5D0\uC11C \uC77D\uC74C). \uD658\uACBD\uBCC0\uC218\uAC00 \uC5C6\uC73C\uBA74 \uC0AC\uC6A9\uC790\uC5D0\uAC8C MCP \uC124\uC815 \uD30C\uC77C\uC758 env \uD544\uB4DC\uC5D0 NWORKS_CLIENT_SECRET \uCD94\uAC00\uB97C \uC548\uB0B4\uD558\uC138\uC694.`;
605
609
  }
606
610
  return `Error: ${err.message}`;
607
611
  }
@@ -2103,7 +2107,7 @@ async function runChecks(profile) {
2103
2107
  creds = await loadCredentials(profile);
2104
2108
  results.push({ check: "credentials", status: "OK", detail: `clientId: ${creds.clientId}` });
2105
2109
  } catch {
2106
- results.push({ check: "credentials", status: "FAIL", detail: "\uC778\uC99D \uC815\uBCF4 \uC5C6\uC74C. `nworks login` \uB610\uB294 nworks_setup \uD544\uC694" });
2110
+ results.push({ check: "credentials", status: "FAIL", detail: "\uC778\uC99D \uC815\uBCF4 \uC5C6\uC74C. CLI: `nworks login --user` / MCP: nworks_setup tool \uC0AC\uC6A9 (\uD658\uACBD\uBCC0\uC218 NWORKS_CLIENT_SECRET \uD544\uC694)" });
2107
2111
  return results;
2108
2112
  }
2109
2113
  if (hasServiceAccountCreds(creds)) {
@@ -2205,39 +2209,69 @@ var doctorCommand = new Command11("doctor").description("Check nworks configurat
2205
2209
  function registerTools(server) {
2206
2210
  server.tool(
2207
2211
  "nworks_setup",
2208
- "NAVER WORKS API \uC778\uC99D \uC815\uBCF4\uB97C \uC124\uC815\uD569\uB2C8\uB2E4. clientId\uB294 \uD544\uC218, clientSecret\uC740 \uD658\uACBD\uBCC0\uC218(NWORKS_CLIENT_SECRET)\uB85C\uB3C4 \uC124\uC815 \uAC00\uB2A5\uD569\uB2C8\uB2E4. \uBBFC\uAC10 \uC815\uBCF4\uB294 \uD658\uACBD\uBCC0\uC218\uB85C \uC124\uC815\uD558\uB294 \uAC83\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4 (NWORKS_CLIENT_ID, NWORKS_CLIENT_SECRET \uB4F1). \uBA54\uC2DC\uC9C0/\uAD6C\uC131\uC6D0\uC870\uD68C\uB294 Service Account \uC778\uC99D(serviceAccount, privateKeyPath, botId \uCD94\uAC00 \uD544\uC694). \uCE98\uB9B0\uB354/\uBA54\uC77C/\uD560\uC77C/\uB4DC\uB77C\uC774\uBE0C/\uAC8C\uC2DC\uD310\uC740 User OAuth \uC778\uC99D(\uC124\uC815 \uD6C4 nworks_login_user\uB85C \uBE0C\uB77C\uC6B0\uC800 \uB85C\uADF8\uC778 \uD544\uC694). OAuth Redirect URI: http://localhost:9876/callback",
2212
+ `NAVER WORKS API \uC778\uC99D \uC815\uBCF4\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.
2213
+
2214
+ \u25A0 \uC0AC\uC804 \uC900\uBE44 (\uC0AC\uC6A9\uC790\uAC00 \uC9C1\uC811 \uD574\uC57C \uD568):
2215
+ 1. https://dev.worksmobile.com \uC5D0\uC11C \uC571 \uC0DD\uC131 \uD6C4 Client ID\uC640 Client Secret\uC744 \uBC1C\uAE09\uBC1B\uC2B5\uB2C8\uB2E4.
2216
+ 2. MCP \uC124\uC815 \uD30C\uC77C(\uC608: claude_desktop_config.json)\uC758 nworks \uC11C\uBC84\uC5D0 env \uD544\uB4DC\uB97C \uCD94\uAC00\uD569\uB2C8\uB2E4:
2217
+ { "env": { "NWORKS_CLIENT_SECRET": "<\uBC1C\uAE09\uBC1B\uC740 Client Secret>" } }
2218
+ 3. MCP \uD074\uB77C\uC774\uC5B8\uD2B8(\uC608: Claude Desktop)\uB97C \uC7AC\uC2DC\uC791\uD569\uB2C8\uB2E4.
2219
+
2220
+ \u25A0 \uC774 tool\uC758 \uC5ED\uD560:
2221
+ - clientId(\uD544\uC218)\uC640 serviceAccount, botId, domainId(\uC120\uD0DD)\uB97C \uD30C\uB77C\uBBF8\uD130\uB85C \uBC1B\uC544 \uC800\uC7A5\uD569\uB2C8\uB2E4.
2222
+ - Client Secret\uC740 \uBCF4\uC548\uC744 \uC704\uD574 \uD30C\uB77C\uBBF8\uD130\uB85C \uBC1B\uC9C0 \uC54A\uC73C\uBA70, \uD658\uACBD\uBCC0\uC218 NWORKS_CLIENT_SECRET\uC5D0\uC11C \uC790\uB3D9\uC73C\uB85C \uC77D\uC2B5\uB2C8\uB2E4.
2223
+ - Service Account \uC0AC\uC6A9 \uC2DC \uD658\uACBD\uBCC0\uC218 NWORKS_PRIVATE_KEY_PATH\uB3C4 \uD544\uC694\uD569\uB2C8\uB2E4.
2224
+
2225
+ \u25A0 \uC124\uC815 \uD6C4 \uB2E4\uC74C \uB2E8\uACC4:
2226
+ - \uCE98\uB9B0\uB354/\uBA54\uC77C/\uB4DC\uB77C\uC774\uBE0C/\uD560\uC77C/\uAC8C\uC2DC\uD310 \u2192 nworks_login_user tool\uB85C \uBE0C\uB77C\uC6B0\uC800 \uB85C\uADF8\uC778 \uD544\uC694
2227
+ - \uBA54\uC2DC\uC9C0/\uAD6C\uC131\uC6D0\uC870\uD68C \u2192 Service Account \uC778\uC99D (serviceAccount + botId + NWORKS_PRIVATE_KEY_PATH)
2228
+
2229
+ \u25A0 \uD658\uACBD\uBCC0\uC218 NWORKS_CLIENT_SECRET\uC774 \uC5C6\uC73C\uBA74 \uC774 tool\uC740 \uC2E4\uD328\uD569\uB2C8\uB2E4. \uC2E4\uD328 \uC2DC \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC704 \uC0AC\uC804 \uC900\uBE44 \uB2E8\uACC4\uB97C \uC548\uB0B4\uD558\uC138\uC694.
2230
+
2231
+ OAuth Redirect URI: http://localhost:9876/callback`,
2209
2232
  {
2210
2233
  clientId: z.string().describe("Client ID (Developer Console\uC5D0\uC11C \uBC1C\uAE09)"),
2211
- clientSecret: z.string().optional().describe("Client Secret (Developer Console\uC5D0\uC11C \uBC1C\uAE09). \uD658\uACBD\uBCC0\uC218 NWORKS_CLIENT_SECRET\uC774 \uC124\uC815\uB418\uC5B4 \uC788\uC73C\uBA74 \uC0DD\uB7B5 \uAC00\uB2A5"),
2212
2234
  serviceAccount: z.string().optional().describe("Service Account ID (\uC608: xxxxx.serviceaccount@domain)"),
2213
- privateKeyPath: z.string().optional().describe("Private Key \uD30C\uC77C\uC758 \uB85C\uCEEC \uC808\uB300 \uACBD\uB85C (\uC11C\uBE44\uC2A4 \uACC4\uC815 \uC778\uC99D \uC2DC \uD544\uC694). \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uD30C\uC77C\uC774 \uC800\uC7A5\uB41C \uACBD\uB85C\uB97C \uC9C1\uC811 \uBB3C\uC5B4\uBCF4\uC138\uC694 (\uC608: C:\\Users\\me\\Downloads\\private.key). \uD30C\uC77C \uC5C5\uB85C\uB4DC\uAC00 \uC544\uB2CC \uACBD\uB85C \uBB38\uC790\uC5F4\uC785\uB2C8\uB2E4."),
2214
2235
  botId: z.string().optional().describe("Bot ID (\uBA54\uC2DC\uC9C0 \uC804\uC1A1 \uC2DC \uD544\uC694)"),
2215
2236
  domainId: z.string().optional().describe("Domain ID")
2216
2237
  },
2217
- async ({ clientId, clientSecret, serviceAccount, privateKeyPath, botId, domainId }) => {
2238
+ async ({ clientId, serviceAccount, botId, domainId }) => {
2218
2239
  try {
2219
- const resolvedSecret = clientSecret || process.env["NWORKS_CLIENT_SECRET"];
2240
+ const resolvedSecret = process.env["NWORKS_CLIENT_SECRET"];
2220
2241
  if (!resolvedSecret) {
2221
2242
  return {
2222
- content: [{ type: "text", text: JSON.stringify({ error: true, message: "clientSecret\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uD30C\uB77C\uBBF8\uD130\uB85C \uC804\uB2EC\uD558\uAC70\uB098 \uD658\uACBD\uBCC0\uC218 NWORKS_CLIENT_SECRET\uC744 \uC124\uC815\uD558\uC138\uC694." }) }],
2243
+ content: [{ type: "text", text: JSON.stringify({
2244
+ error: true,
2245
+ message: "\uD658\uACBD\uBCC0\uC218 NWORKS_CLIENT_SECRET\uC774 \uC124\uC815\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
2246
+ userAction: [
2247
+ "1. https://dev.worksmobile.com \uC5D0\uC11C \uC571\uC758 Client Secret\uC744 \uD655\uC778\uD569\uB2C8\uB2E4.",
2248
+ "2. MCP \uC124\uC815 \uD30C\uC77C(\uC608: claude_desktop_config.json)\uC744 \uC5F4\uACE0, nworks \uC11C\uBC84 \uC124\uC815\uC5D0 \uB2E4\uC74C\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4:",
2249
+ ' "env": { "NWORKS_CLIENT_SECRET": "<Client Secret>" }',
2250
+ "3. MCP \uD074\uB77C\uC774\uC5B8\uD2B8(\uC608: Claude Desktop)\uB97C \uC7AC\uC2DC\uC791\uD569\uB2C8\uB2E4.",
2251
+ "4. \uC7AC\uC2DC\uC791 \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694."
2252
+ ],
2253
+ configExample: '{ "mcpServers": { "nworks": { "command": "npx", "args": ["-y", "nworks", "mcp"], "env": { "NWORKS_CLIENT_SECRET": "<Client Secret>" } } } }'
2254
+ }) }],
2223
2255
  isError: true
2224
2256
  };
2225
2257
  }
2258
+ const resolvedPrivateKeyPath = process.env["NWORKS_PRIVATE_KEY_PATH"];
2226
2259
  await saveCredentials({
2227
2260
  clientId,
2228
2261
  clientSecret: resolvedSecret,
2229
2262
  serviceAccount,
2230
- privateKeyPath,
2263
+ privateKeyPath: resolvedPrivateKeyPath,
2231
2264
  botId,
2232
2265
  domainId
2233
2266
  });
2234
2267
  const nextSteps = [];
2235
- if (serviceAccount && privateKeyPath && botId) {
2268
+ if (serviceAccount && resolvedPrivateKeyPath && botId) {
2236
2269
  nextSteps.push("Service Account \uC778\uC99D \uC900\uBE44 \uC644\uB8CC \u2014 \uBD07 \uBA54\uC2DC\uC9C0 \uB4F1 \uBC14\uB85C \uC0AC\uC6A9 \uAC00\uB2A5");
2270
+ } else if (serviceAccount && botId && !resolvedPrivateKeyPath) {
2271
+ nextSteps.push('NWORKS_PRIVATE_KEY_PATH \uD658\uACBD\uBCC0\uC218\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. Service Account \uC778\uC99D\uC5D0\uB294 Private Key \uD30C\uC77C \uACBD\uB85C\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC548\uB0B4\uD558\uC138\uC694: (1) Developer Console(https://dev.worksmobile.com)\uC5D0\uC11C Private Key\uB97C \uB2E4\uC6B4\uB85C\uB4DC (2) MCP \uC124\uC815 \uD30C\uC77C\uC758 env\uC5D0 NWORKS_PRIVATE_KEY_PATH\uB97C \uCD94\uAC00 (\uC608: "NWORKS_PRIVATE_KEY_PATH": "C:/keys/private.key") (3) MCP \uD074\uB77C\uC774\uC5B8\uD2B8 \uC7AC\uC2DC\uC791');
2237
2272
  }
2238
2273
  nextSteps.push("User OAuth\uAC00 \uD544\uC694\uD55C API\uB294 nworks_login_user tool\uB85C \uBE0C\uB77C\uC6B0\uC800 \uB85C\uADF8\uC778\uC744 \uC9C4\uD589\uD558\uC138\uC694");
2239
2274
  const mask = (s) => s.length <= 4 ? "****" : `****${s.slice(-Math.min(4, Math.floor(s.length / 3)))}`;
2240
- const secretSource = clientSecret ? "\uD30C\uB77C\uBBF8\uD130" : "\uD658\uACBD\uBCC0\uC218";
2241
2275
  return {
2242
2276
  content: [
2243
2277
  {
@@ -2247,9 +2281,9 @@ function registerTools(server) {
2247
2281
  message: "\uC778\uC99D \uC815\uBCF4\uAC00 \uC800\uC7A5\uB418\uC5C8\uC2B5\uB2C8\uB2E4.",
2248
2282
  nextSteps,
2249
2283
  clientId,
2250
- clientSecret: `${mask(resolvedSecret)} (${secretSource})`,
2284
+ clientSecret: `${mask(resolvedSecret)} (\uD658\uACBD\uBCC0\uC218)`,
2251
2285
  serviceAccount: serviceAccount ?? null,
2252
- privateKeyPath: privateKeyPath ? mask(privateKeyPath) : null,
2286
+ privateKeyPath: resolvedPrivateKeyPath ? `${mask(resolvedPrivateKeyPath)} (\uD658\uACBD\uBCC0\uC218)` : null,
2253
2287
  botId: botId ?? null
2254
2288
  })
2255
2289
  }
@@ -2265,7 +2299,7 @@ function registerTools(server) {
2265
2299
  );
2266
2300
  server.tool(
2267
2301
  "nworks_message_send",
2268
- "NAVER WORKS \uBA54\uC2DC\uC9C0\uB97C \uC804\uC1A1\uD569\uB2C8\uB2E4 (\uBD07\uC774 \uC0AC\uC6A9\uC790 \uB610\uB294 \uCC44\uB110\uC5D0 \uBC1C\uC1A1). Service Account \uC778\uC99D \uC0AC\uC6A9 (nworks_setup\uC5D0\uC11C serviceAccount, privateKeyPath, botId \uC124\uC815 \uD544\uC694. User OAuth \uBD88\uD544\uC694)",
2302
+ "NAVER WORKS \uBA54\uC2DC\uC9C0\uB97C \uC804\uC1A1\uD569\uB2C8\uB2E4 (\uBD07\uC774 \uC0AC\uC6A9\uC790 \uB610\uB294 \uCC44\uB110\uC5D0 \uBC1C\uC1A1). Service Account \uC778\uC99D \uC0AC\uC6A9 (nworks_setup\uC5D0\uC11C serviceAccount, botId \uC124\uC815 + \uD658\uACBD\uBCC0\uC218 NWORKS_PRIVATE_KEY_PATH \uD544\uC694. User OAuth \uBD88\uD544\uC694)",
2269
2303
  {
2270
2304
  to: z.string().optional().describe("\uC218\uC2E0\uC790 userId (channel\uACFC \uD0DD 1). nworks_directory_members\uB85C userId \uC870\uD68C \uAC00\uB2A5"),
2271
2305
  channel: z.string().optional().describe("\uCC44\uB110 channelId (to\uC640 \uD0DD 1). nworks_message_members\uB85C \uCC44\uB110 \uAD6C\uC131\uC6D0 \uD655\uC778 \uAC00\uB2A5"),
@@ -3080,7 +3114,7 @@ function registerTools(server) {
3080
3114
  type: "text",
3081
3115
  text: JSON.stringify({
3082
3116
  success: true,
3083
- message: "\uC778\uC99D \uC815\uBCF4\uC640 \uD1A0\uD070\uC774 \uBAA8\uB450 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC0AC\uC6A9\uD558\uB824\uBA74 nworks_setup tool\uB85C \uC7AC\uC124\uC815\uD558\uC138\uC694."
3117
+ message: "\uC778\uC99D \uC815\uBCF4\uC640 \uD1A0\uD070\uC774 \uBAA8\uB450 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC0AC\uC6A9\uD558\uB824\uBA74 nworks_setup tool\uB85C \uC7AC\uC124\uC815 \uD6C4 nworks_login_user\uB85C \uBE0C\uB77C\uC6B0\uC800 \uB85C\uADF8\uC778\uD558\uC138\uC694."
3084
3118
  })
3085
3119
  }
3086
3120
  ]