nworks_login_user
Initiate user OAuth login for NAVER WORKS to access calendar, mail, drive, tasks, and boards. Open the returned URL in a browser to authenticate and automatically store tokens for full API functionality.
Instructions
User OAuth 로그인을 시작합니다. 반환된 URL을 브라우저에서 열어 NAVER WORKS에 로그인하세요. 로그인 완료 후 자동으로 토큰이 저장됩니다. 중요: scope를 지정하지 마세요. 기본값이 모든 API(캘린더, 메일, 할일, 드라이브, 게시판)를 포함하므로 한 번 로그인으로 전체 기능을 사용할 수 있습니다. scope를 좁게 지정하면 다른 기능 사용 시 재로그인이 필요합니다.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | 지정하지 마세요 (기본값이 전체 scope 포함). 특수한 경우에만 사용 |
Implementation Reference
- src/mcp/tools.ts:908-988 (handler)The handler for `nworks_login_user`, which initiates the User OAuth flow by generating an authorization URL and starting a local callback server.
server.tool( "nworks_login_user", "User OAuth 로그인을 시작합니다. 반환된 URL을 브라우저에서 열어 NAVER WORKS에 로그인하세요. 로그인 완료 후 자동으로 토큰이 저장됩니다. 중요: scope를 지정하지 마세요. 기본값이 모든 API(캘린더, 메일, 할일, 드라이브, 게시판)를 포함하므로 한 번 로그인으로 전체 기능을 사용할 수 있습니다. scope를 좁게 지정하면 다른 기능 사용 시 재로그인이 필요합니다.", { scope: z .string() .optional() .describe("지정하지 마세요 (기본값이 전체 scope 포함). 특수한 경우에만 사용"), }, async ({ scope }) => { const DEFAULT_SCOPE = "calendar calendar.read file file.read mail mail.read task task.read user.read board board.read"; try { const creds = await loadCredentials(); // scope 의존성 자동 확장 // - calendar 쓰기는 calendar.read 필요 (수정/삭제 시 기존 일정 조회) // - task 쓰기는 user.read 필요 (/users/me 호출) const SCOPE_DEPS: Record<string, string[]> = { calendar: ["calendar.read"], task: ["user.read"], "task.read": ["user.read"], }; const expandScopes = (scopes: string[]): string[] => { const expanded = new Set(scopes); for (const s of scopes) { const deps = SCOPE_DEPS[s]; if (deps) deps.forEach((d) => expanded.add(d)); } return [...expanded]; }; // 기존 토큰의 scope와 합치기 const existingToken = await loadUserToken(); const existingScopes = existingToken?.scope?.split(" ").filter(Boolean) ?? []; const requestedScopes = expandScopes((scope ?? DEFAULT_SCOPE).split(" ").filter(Boolean)); const mergedScopes = [...new Set([...existingScopes, ...requestedScopes])].join(" "); const state = generateSecureState(); const authorizeUrl = buildAuthorizeUrl(creds.clientId, mergedScopes, state); // 콜백 서버를 백그라운드로 시작 (토큰 교환 및 저장까지 자동 처리) startOAuthCallbackServer(creds.clientId, creds.clientSecret, state) .then((token) => saveUserToken({ accessToken: token.accessToken, refreshToken: token.refreshToken, expiresAt: token.expiresAt, scope: token.scope, }) ) .then(() => { console.error("[nworks] User OAuth login successful. Token saved."); }) .catch((err: Error) => { console.error(`[nworks] User OAuth login failed: ${err.message}`); }); return { content: [ { type: "text" as const, text: JSON.stringify({ message: "아래 URL을 브라우저에서 열어 NAVER WORKS에 로그인하세요. 로그인 완료 후 자동으로 토큰이 저장됩니다. (제한시간: 120초)", loginUrl: authorizeUrl, scope: mergedScopes, callbackPort: 9876, timeout: "120초", }), }, ], }; } catch (err) { return { content: [{ type: "text" as const, text: mcpErrorHint(err) }], isError: true, }; } } );