Skip to main content
Glama
taylorwilsdon

Google Workspace MCP Server - Control Gmail, Calendar, Docs, Sheets, Slides, Chat, Forms & Drive

start_google_auth

Initiates Google OAuth 2.0 authentication to grant access to specific Google services like Gmail, Drive, or Calendar. Generates an authorization URL for users to complete sign-in, enabling secure credential establishment for the current session.

Instructions

Initiates the Google OAuth 2.0 authentication flow for the specified user email and service.
This is the primary method to establish credentials when no valid session exists or when targeting a specific account for a particular service.
It generates an authorization URL that the LLM must present to the user.
The authentication attempt is linked to the current MCP session via `mcp_session_id`.

LLM Guidance:
- Use this tool when you need to authenticate a user for a specific Google service (e.g., "Google Calendar", "Google Docs", "Gmail", "Google Drive")
  and don't have existing valid credentials for the session or specified email.
- You MUST provide the `user_google_email` and the `service_name`. If you don't know the email, ask the user first.
- Valid `service_name` values typically include "Google Calendar", "Google Docs", "Gmail", "Google Drive".
- After calling this tool, present the returned authorization URL clearly to the user and instruct them to:
    1. Click the link and complete the sign-in/consent process in their browser.
    2. Note the authenticated email displayed on the success page.
    3. Provide that email back to you (the LLM).
    4. Retry their original request, including the confirmed `user_google_email`.

Args:
    user_google_email (str): The user's full Google email address (e.g., 'example@gmail.com'). This is REQUIRED.
    service_name (str): The name of the Google service for which authentication is being requested (e.g., "Google Calendar", "Google Docs"). This is REQUIRED.
    mcp_session_id (Optional[str]): The active MCP session ID (automatically injected by FastMCP from the Mcp-Session-Id header). Links the OAuth flow state to the session.

Returns:
    str: A detailed message for the LLM with the authorization URL and instructions to guide the user through the authentication process.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
mcp_session_idNo
service_nameYes
user_google_emailYes

Implementation Reference

  • The primary handler for the 'start_google_auth' tool. Decorated with @server.tool() for MCP registration. Validates inputs, checks client secrets, and delegates to start_auth_flow helper to generate OAuth URL and instructions.
    @server.tool()
    async def start_google_auth(service_name: str, user_google_email: str = USER_GOOGLE_EMAIL) -> str:
        """
        Manually initiate Google OAuth authentication flow.
    
        NOTE: This tool should typically NOT be called directly. The authentication system
        automatically handles credential checks and prompts for authentication when needed.
        Only use this tool if:
        1. You need to re-authenticate with different credentials
        2. You want to proactively authenticate before using other tools
        3. The automatic authentication flow failed and you need to retry
    
        In most cases, simply try calling the Google Workspace tool you need - it will
        automatically handle authentication if required.
        """
        if not user_google_email:
            raise ValueError("user_google_email must be provided.")
    
        error_message = check_client_secrets()
        if error_message:
            return f"**Authentication Error:** {error_message}"
    
        try:
            auth_message = await start_auth_flow(
                user_google_email=user_google_email,
                service_name=service_name,
                redirect_uri=get_oauth_redirect_uri_for_current_mode()
            )
            return auth_message
        except Exception as e:
            logger.error(f"Failed to start Google authentication flow: {e}", exc_info=True)
            return f"**Error:** An unexpected error occurred: {e}"
  • Key helper function called by the tool handler. Creates OAuth Flow, generates authorization URL, stores state for callback validation, and returns formatted instructions including the clickable auth URL for the user.
    async def start_auth_flow(
        user_google_email: Optional[str],
        service_name: str,  # e.g., "Google Calendar", "Gmail" for user messages
        redirect_uri: str,  # Added redirect_uri as a required parameter
    ) -> str:
        """
        Initiates the Google OAuth flow and returns an actionable message for the user.
    
        Args:
            user_google_email: The user's specified Google email, if provided.
            service_name: The name of the Google service requiring auth (for user messages).
            redirect_uri: The URI Google will redirect to after authorization.
    
        Returns:
            A formatted string containing guidance for the LLM/user.
    
        Raises:
            Exception: If the OAuth flow cannot be initiated.
        """
        initial_email_provided = bool(
            user_google_email
            and user_google_email.strip()
            and user_google_email.lower() != "default"
        )
        user_display_name = (
            f"{service_name} for '{user_google_email}'"
            if initial_email_provided
            else service_name
        )
    
        logger.info(
            f"[start_auth_flow] Initiating auth for {user_display_name} with scopes for enabled tools."
        )
    
        # Note: Caller should ensure OAuth callback is available before calling this function
    
        try:
            if "OAUTHLIB_INSECURE_TRANSPORT" not in os.environ and (
                "localhost" in redirect_uri or "127.0.0.1" in redirect_uri
            ):  # Use passed redirect_uri
                logger.warning(
                    "OAUTHLIB_INSECURE_TRANSPORT not set. Setting it for localhost/local development."
                )
                os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
    
            oauth_state = os.urandom(16).hex()
    
            flow = create_oauth_flow(
                scopes=get_current_scopes(),  # Use scopes for enabled tools only
                redirect_uri=redirect_uri,  # Use passed redirect_uri
                state=oauth_state,
            )
    
            auth_url, _ = flow.authorization_url(access_type="offline", prompt="consent")
    
            session_id = None
            try:
                session_id = get_fastmcp_session_id()
            except Exception as e:
                logger.debug(f"Could not retrieve FastMCP session ID for state binding: {e}")
    
            store = get_oauth21_session_store()
            store.store_oauth_state(oauth_state, session_id=session_id)
    
            logger.info(
                f"Auth flow started for {user_display_name}. State: {oauth_state[:8]}... Advise user to visit: {auth_url}"
            )
    
            message_lines = [
                f"**ACTION REQUIRED: Google Authentication Needed for {user_display_name}**\n",
                f"To proceed, the user must authorize this application for {service_name} access using all required permissions.",
                "**LLM, please present this exact authorization URL to the user as a clickable hyperlink:**",
                f"Authorization URL: {auth_url}",
                f"Markdown for hyperlink: [Click here to authorize {service_name} access]({auth_url})\n",
                "**LLM, after presenting the link, instruct the user as follows:**",
                "1. Click the link and complete the authorization in their browser.",
            ]
            session_info_for_llm = ""
    
            if not initial_email_provided:
                message_lines.extend(
                    [
                        f"2. After successful authorization{session_info_for_llm}, the browser page will display the authenticated email address.",
                        "   **LLM: Instruct the user to provide you with this email address.**",
                        "3. Once you have the email, **retry their original command, ensuring you include this `user_google_email`.**",
                    ]
                )
            else:
                message_lines.append(
                    f"2. After successful authorization{session_info_for_llm}, **retry their original command**."
                )
    
            message_lines.append(
                f"\nThe application will use the new credentials. If '{user_google_email}' was provided, it must match the authenticated account."
            )
            return "\n".join(message_lines)
    
        except FileNotFoundError as e:
            error_text = f"OAuth client credentials not found: {e}. Please either:\n1. Set environment variables: GOOGLE_OAUTH_CLIENT_ID and GOOGLE_OAUTH_CLIENT_SECRET\n2. Ensure '{CONFIG_CLIENT_SECRETS_PATH}' file exists"
            logger.error(error_text, exc_info=True)
            raise Exception(error_text)
        except Exception as e:
            error_text = f"Could not initiate authentication for {user_display_name} due to an unexpected error: {str(e)}"
            logger.error(
                f"Failed to start the OAuth flow for {user_display_name}: {e}",
                exc_info=True,
            )
            raise Exception(error_text)
  • Helper function used by the tool to validate OAuth client secrets configuration before starting the auth flow.
    def check_client_secrets() -> Optional[str]:
        """
        Checks for the presence of OAuth client secrets, either as environment
        variables or as a file.
    
        Returns:
            An error message string if secrets are not found, otherwise None.
        """
        env_config = load_client_secrets_from_env()
        if not env_config and not os.path.exists(CONFIG_CLIENT_SECRETS_PATH):
            logger.error(
                f"OAuth client credentials not found. No environment variables set and no file at {CONFIG_CLIENT_SECRETS_PATH}"
            )
            return f"OAuth client credentials not found. Please set GOOGLE_OAUTH_CLIENT_ID and GOOGLE_OAUTH_CLIENT_SECRET environment variables or provide a client secrets file at {CONFIG_CLIENT_SECRETS_PATH}."
        return None
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full behavioral disclosure burden. It effectively describes the tool's behavior: generates authorization URLs, links authentication to MCP sessions, requires user interaction, and provides detailed post-call instructions. It doesn't mention rate limits or error conditions, but covers the core authentication flow comprehensively.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (purpose, LLM Guidance, Args, Returns) but could be more concise. The 'LLM Guidance' section contains some redundancy (e.g., repeating service examples). However, every sentence serves a purpose in guiding the agent through the authentication workflow.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an authentication tool with 3 parameters, no annotations, and no output schema, the description provides exceptional completeness. It covers the authentication flow, parameter requirements, valid values, session linking, and detailed post-call instructions. The agent has all necessary context to use this tool correctly without additional documentation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 0% schema description coverage, the description provides extensive parameter semantics in the 'Args' section. It explains each parameter's purpose, provides examples, clarifies requirements ('REQUIRED'), and offers guidance on valid values for service_name. This fully compensates for the schema's lack of descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Initiates the Google OAuth 2.0 authentication flow') and target resources ('for the specified user email and service'). It distinguishes itself from sibling tools by focusing exclusively on authentication initiation rather than document/event/content operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'LLM Guidance' section provides explicit when-to-use instructions ('when you need to authenticate... and don't have existing valid credentials'), clear prerequisites ('MUST provide user_google_email and service_name'), and specific alternatives ('If you don't know the email, ask the user first'). It also outlines the complete workflow after tool invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

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/taylorwilsdon/google_workspace_mcp'

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