Skip to main content
Glama

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
NameRequiredDescriptionDefault
scopeNo지정하지 마세요 (기본값이 전체 scope 포함). 특수한 경우에만 사용

Implementation Reference

  • 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,
          };
        }
      }
    );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yjcho9317/nworks'

If you have feedback or need assistance with the MCP directory API, please join our Discord server