diff --git a/core/tool_tiers.yaml b/core/tool_tiers.yaml
index 6ba8565..eaa47b4 100644
--- a/core/tool_tiers.yaml
+++ b/core/tool_tiers.yaml
@@ -24,7 +24,9 @@ drive:
     - create_drive_file
   extended:
     - list_drive_items
-  complete: []
+  complete:
+    - get_drive_file_permissions
+    - check_drive_file_public_access
 
 calendar:
   core:
diff --git a/core/utils.py b/core/utils.py
index 36fb154..2418bbd 100644
--- a/core/utils.py
+++ b/core/utils.py
@@ -295,12 +295,16 @@ def handle_http_errors(tool_name: str, is_read_only: bool = False, service_type:
                                 f"The required API is not enabled for your project. "
                                 f"Please check the Google Cloud Console to enable it."
                             )
-                    else:
+                    elif error.resp.status in [401, 403]:
+                        # Authentication/authorization errors
                         message = (
                             f"API error in {tool_name}: {error}. "
                             f"You might need to re-authenticate for user '{user_google_email}'. "
                             f"LLM: Try 'start_google_auth' with the user's email and the appropriate service_name."
                         )
+                    else:
+                        # Other HTTP errors (400 Bad Request, etc.) - don't suggest re-auth
+                        message = f"API error in {tool_name}: {error}"
                     
                     logger.error(f"API error in {tool_name}: {error}", exc_info=True)
                     raise Exception(message) from error
diff --git a/gdocs/docs_helpers.py b/gdocs/docs_helpers.py
index a59d668..1394085 100644
--- a/gdocs/docs_helpers.py
+++ b/gdocs/docs_helpers.py
@@ -72,6 +72,28 @@ def create_insert_text_request(index: int, text: str) -> Dict[str, Any]:
         }
     }
 
+def create_insert_text_segment_request(index: int, text: str, segment_id: str) -> Dict[str, Any]:
+    """
+    Create an insertText request for Google Docs API with segmentId (for headers/footers).
+    
+    Args:
+        index: Position to insert text
+        text: Text to insert
+        segment_id: Segment ID (for targeting headers/footers)
+    
+    Returns:
+        Dictionary representing the insertText request with segmentId
+    """
+    return {
+        'insertText': {
+            'location': {
+                'segmentId': segment_id,
+                'index': index
+            },
+            'text': text
+        }
+    }
+
 def create_delete_range_request(start_index: int, end_index: int) -> Dict[str, Any]:
     """
     Create a deleteContentRange request for Google Docs API.
diff --git a/gdrive/drive_helpers.py b/gdrive/drive_helpers.py
new file mode 100644
index 0000000..74de7c6
--- /dev/null
+++ b/gdrive/drive_helpers.py
@@ -0,0 +1,110 @@
+"""
+Google Drive Helper Functions
+
+Shared utilities for Google Drive operations including permission checking.
+"""
+import re
+from typing import List, Dict, Any, Optional
+
+
+def check_public_link_permission(permissions: List[Dict[str, Any]]) -> bool:
+    """
+    Check if file has 'anyone with the link' permission.
+    
+    Args:
+        permissions: List of permission objects from Google Drive API
+        
+    Returns:
+        bool: True if file has public link sharing enabled
+    """
+    return any(
+        p.get('type') == 'anyone' and p.get('role') in ['reader', 'writer', 'commenter']
+        for p in permissions
+    )
+
+
+def format_public_sharing_error(file_name: str, file_id: str) -> str:
+    """
+    Format error message for files without public sharing.
+    
+    Args:
+        file_name: Name of the file
+        file_id: Google Drive file ID
+        
+    Returns:
+        str: Formatted error message
+    """
+    return (
+        f"❌ Permission Error: '{file_name}' not shared publicly. "
+        f"Set 'Anyone with the link' → 'Viewer' in Google Drive sharing. "
+        f"File: https://drive.google.com/file/d/{file_id}/view"
+    )
+
+
+def get_drive_image_url(file_id: str) -> str:
+    """
+    Get the correct Drive URL format for publicly shared images.
+    
+    Args:
+        file_id: Google Drive file ID
+        
+    Returns:
+        str: URL for embedding Drive images
+    """
+    return f"https://drive.google.com/uc?export=view&id={file_id}"
+
+
+# Precompiled regex patterns for Drive query detection
+DRIVE_QUERY_PATTERNS = [
+    re.compile(r'\b\w+\s*(=|!=|>|<)\s*[\'"].*?[\'"]', re.IGNORECASE),  # field = 'value'
+    re.compile(r'\b\w+\s*(=|!=|>|<)\s*\d+', re.IGNORECASE),            # field = number
+    re.compile(r'\bcontains\b', re.IGNORECASE),                         # contains operator
+    re.compile(r'\bin\s+parents\b', re.IGNORECASE),                     # in parents
+    re.compile(r'\bhas\s*\{', re.IGNORECASE),                          # has {properties}
+    re.compile(r'\btrashed\s*=\s*(true|false)\b', re.IGNORECASE),      # trashed=true/false
+    re.compile(r'\bstarred\s*=\s*(true|false)\b', re.IGNORECASE),      # starred=true/false
+    re.compile(r'[\'"][^\'"]+[\'"]\s+in\s+parents', re.IGNORECASE),    # 'parentId' in parents
+    re.compile(r'\bfullText\s+contains\b', re.IGNORECASE),             # fullText contains
+    re.compile(r'\bname\s*(=|contains)\b', re.IGNORECASE),             # name = or name contains
+    re.compile(r'\bmimeType\s*(=|!=)\b', re.IGNORECASE),               # mimeType operators
+]
+
+
+def build_drive_list_params(
+    query: str,
+    page_size: int,
+    drive_id: Optional[str] = None,
+    include_items_from_all_drives: bool = True,
+    corpora: Optional[str] = None,
+) -> Dict[str, Any]:
+    """
+    Helper function to build common list parameters for Drive API calls.
+
+    Args:
+        query: The search query string
+        page_size: Maximum number of items to return
+        drive_id: Optional shared drive ID
+        include_items_from_all_drives: Whether to include items from all drives
+        corpora: Optional corpus specification
+
+    Returns:
+        Dictionary of parameters for Drive API list calls
+    """
+    list_params = {
+        "q": query,
+        "pageSize": page_size,
+        "fields": "nextPageToken, files(id, name, mimeType, webViewLink, iconLink, modifiedTime, size)",
+        "supportsAllDrives": True,
+        "includeItemsFromAllDrives": include_items_from_all_drives,
+    }
+
+    if drive_id:
+        list_params["driveId"] = drive_id
+        if corpora:
+            list_params["corpora"] = corpora
+        else:
+            list_params["corpora"] = "drive"
+    elif corpora:
+        list_params["corpora"] = corpora
+
+    return list_params
\ No newline at end of file
diff --git a/gdrive/drive_tools.py b/gdrive/drive_tools.py
index 6801d0d..ba103e6 100644
--- a/gdrive/drive_tools.py
+++ b/gdrive/drive_tools.py
@@ -5,8 +5,7 @@ This module provides MCP tools for interacting with Google Drive API.
 """
 import logging
 import asyncio
-import re
-from typing import Optional, Dict, Any
+from typing import Optional
 
 from googleapiclient.http import MediaIoBaseDownload, MediaIoBaseUpload
 import io
@@ -15,64 +14,10 @@ import httpx
 from auth.service_decorator import require_google_service
 from core.utils import extract_office_xml_text, handle_http_errors
 from core.server import server
+from gdrive.drive_helpers import DRIVE_QUERY_PATTERNS, build_drive_list_params
 
 logger = logging.getLogger(__name__)
 
-# Precompiled regex patterns for Drive query detection
-DRIVE_QUERY_PATTERNS = [
-    re.compile(r'\b\w+\s*(=|!=|>|<)\s*[\'"].*?[\'"]', re.IGNORECASE),  # field = 'value'
-    re.compile(r'\b\w+\s*(=|!=|>|<)\s*\d+', re.IGNORECASE),            # field = number
-    re.compile(r'\bcontains\b', re.IGNORECASE),                         # contains operator
-    re.compile(r'\bin\s+parents\b', re.IGNORECASE),                     # in parents
-    re.compile(r'\bhas\s*\{', re.IGNORECASE),                          # has {properties}
-    re.compile(r'\btrashed\s*=\s*(true|false)\b', re.IGNORECASE),      # trashed=true/false
-    re.compile(r'\bstarred\s*=\s*(true|false)\b', re.IGNORECASE),      # starred=true/false
-    re.compile(r'[\'"][^\'"]+[\'"]\s+in\s+parents', re.IGNORECASE),    # 'parentId' in parents
-    re.compile(r'\bfullText\s+contains\b', re.IGNORECASE),             # fullText contains
-    re.compile(r'\bname\s*(=|contains)\b', re.IGNORECASE),             # name = or name contains
-    re.compile(r'\bmimeType\s*(=|!=)\b', re.IGNORECASE),               # mimeType operators
-]
-
-
-def _build_drive_list_params(
-    query: str,
-    page_size: int,
-    drive_id: Optional[str] = None,
-    include_items_from_all_drives: bool = True,
-    corpora: Optional[str] = None,
-) -> Dict[str, Any]:
-    """
-    Helper function to build common list parameters for Drive API calls.
-
-    Args:
-        query: The search query string
-        page_size: Maximum number of items to return
-        drive_id: Optional shared drive ID
-        include_items_from_all_drives: Whether to include items from all drives
-        corpora: Optional corpus specification
-
-    Returns:
-        Dictionary of parameters for Drive API list calls
-    """
-    list_params = {
-        "q": query,
-        "pageSize": page_size,
-        "fields": "nextPageToken, files(id, name, mimeType, webViewLink, iconLink, modifiedTime, size)",
-        "supportsAllDrives": True,
-        "includeItemsFromAllDrives": include_items_from_all_drives,
-    }
-
-    if drive_id:
-        list_params["driveId"] = drive_id
-        if corpora:
-            list_params["corpora"] = corpora
-        else:
-            list_params["corpora"] = "drive"
-    elif corpora:
-        list_params["corpora"] = corpora
-
-    return list_params
-
 @server.tool()
 @handle_http_errors("search_drive_files", is_read_only=True, service_type="drive")
 @require_google_service("drive", "drive_read")
@@ -116,7 +61,7 @@ async def search_drive_files(
         final_query = f"fullText contains '{escaped_query}'"
         logger.info(f"[search_drive_files] Reformatting free text query '{query}' to '{final_query}'")
 
-    list_params = _build_drive_list_params(
+    list_params = build_drive_list_params(
         query=final_query,
         page_size=page_size,
         drive_id=drive_id,
@@ -262,7 +207,7 @@ async def list_drive_items(
 
     final_query = f"'{folder_id}' in parents and trashed=false"
 
-    list_params = _build_drive_list_params(
+    list_params = build_drive_list_params(
         query=final_query,
         page_size=page_size,
         drive_id=drive_id,
@@ -354,4 +299,198 @@ async def create_drive_file(
     link = created_file.get('webViewLink', 'No link available')
     confirmation_message = f"Successfully created file '{created_file.get('name', file_name)}' (ID: {created_file.get('id', 'N/A')}) in folder '{folder_id}' for {user_google_email}. Link: {link}"
     logger.info(f"Successfully created file. Link: {link}")
-    return confirmation_message
\ No newline at end of file
+    return confirmation_message
+
+@server.tool()
+@handle_http_errors("get_drive_file_permissions", is_read_only=True, service_type="drive")
+@require_google_service("drive", "drive_read")
+async def get_drive_file_permissions(
+    service,
+    user_google_email: str,
+    file_id: str,
+) -> str:
+    """
+    Gets detailed metadata about a Google Drive file including sharing permissions.
+    
+    Args:
+        user_google_email (str): The user's Google email address. Required.
+        file_id (str): The ID of the file to check permissions for.
+    
+    Returns:
+        str: Detailed file metadata including sharing status and URLs.
+    """
+    logger.info(f"[get_drive_file_permissions] Checking file {file_id} for {user_google_email}")
+    
+    try:
+        # Get comprehensive file metadata including permissions
+        file_metadata = await asyncio.to_thread(
+            service.files().get(
+                fileId=file_id,
+                fields="id, name, mimeType, size, modifiedTime, owners, permissions, "
+                       "webViewLink, webContentLink, shared, sharingUser, viewersCanCopyContent",
+                supportsAllDrives=True
+            ).execute
+        )
+        
+        # Format the response
+        output_parts = [
+            f"File: {file_metadata.get('name', 'Unknown')}",
+            f"ID: {file_id}",
+            f"Type: {file_metadata.get('mimeType', 'Unknown')}",
+            f"Size: {file_metadata.get('size', 'N/A')} bytes",
+            f"Modified: {file_metadata.get('modifiedTime', 'N/A')}",
+            "",
+            "Sharing Status:",
+            f"  Shared: {file_metadata.get('shared', False)}",
+        ]
+        
+        # Add sharing user if available
+        sharing_user = file_metadata.get('sharingUser')
+        if sharing_user:
+            output_parts.append(f"  Shared by: {sharing_user.get('displayName', 'Unknown')} ({sharing_user.get('emailAddress', 'Unknown')})")
+        
+        # Process permissions
+        permissions = file_metadata.get('permissions', [])
+        if permissions:
+            output_parts.append(f"  Number of permissions: {len(permissions)}")
+            output_parts.append("  Permissions:")
+            for perm in permissions:
+                perm_type = perm.get('type', 'unknown')
+                role = perm.get('role', 'unknown')
+                
+                if perm_type == 'anyone':
+                    output_parts.append(f"    - Anyone with the link ({role})")
+                elif perm_type == 'user':
+                    email = perm.get('emailAddress', 'unknown')
+                    output_parts.append(f"    - User: {email} ({role})")
+                elif perm_type == 'domain':
+                    domain = perm.get('domain', 'unknown')
+                    output_parts.append(f"    - Domain: {domain} ({role})")
+                elif perm_type == 'group':
+                    email = perm.get('emailAddress', 'unknown')
+                    output_parts.append(f"    - Group: {email} ({role})")
+                else:
+                    output_parts.append(f"    - {perm_type} ({role})")
+        else:
+            output_parts.append("  No additional permissions (private file)")
+        
+        # Add URLs
+        output_parts.extend([
+            "",
+            "URLs:",
+            f"  View Link: {file_metadata.get('webViewLink', 'N/A')}",
+        ])
+        
+        # webContentLink is only available for files that can be downloaded
+        web_content_link = file_metadata.get('webContentLink')
+        if web_content_link:
+            output_parts.append(f"  Direct Download Link: {web_content_link}")
+        
+        # Check if file has "anyone with link" permission
+        from gdrive.drive_helpers import check_public_link_permission
+        has_public_link = check_public_link_permission(permissions)
+        
+        if has_public_link:
+            output_parts.extend([
+                "",
+                "✅ This file is shared with 'Anyone with the link' - it can be inserted into Google Docs"
+            ])
+        else:
+            output_parts.extend([
+                "",
+                "❌ This file is NOT shared with 'Anyone with the link' - it cannot be inserted into Google Docs",
+                "   To fix: Right-click the file in Google Drive → Share → Anyone with the link → Viewer"
+            ])
+        
+        return "\n".join(output_parts)
+        
+    except Exception as e:
+        logger.error(f"Error getting file permissions: {e}")
+        return f"Error getting file permissions: {e}"
+
+
+@server.tool()
+@handle_http_errors("check_drive_file_public_access", is_read_only=True, service_type="drive")
+@require_google_service("drive", "drive_read")
+async def check_drive_file_public_access(
+    service,
+    user_google_email: str,
+    file_name: str,
+) -> str:
+    """
+    Searches for a file by name and checks if it has public link sharing enabled.
+    
+    Args:
+        user_google_email (str): The user's Google email address. Required.
+        file_name (str): The name of the file to check.
+    
+    Returns:
+        str: Information about the file's sharing status and whether it can be used in Google Docs.
+    """
+    logger.info(f"[check_drive_file_public_access] Searching for {file_name}")
+    
+    # Search for the file
+    escaped_name = file_name.replace("'", "\\'")
+    query = f"name = '{escaped_name}'"
+    
+    list_params = {
+        "q": query,
+        "pageSize": 10,
+        "fields": "files(id, name, mimeType, webViewLink)",
+        "supportsAllDrives": True,
+        "includeItemsFromAllDrives": True,
+    }
+    
+    results = await asyncio.to_thread(
+        service.files().list(**list_params).execute
+    )
+    
+    files = results.get('files', [])
+    if not files:
+        return f"No file found with name '{file_name}'"
+    
+    if len(files) > 1:
+        output_parts = [f"Found {len(files)} files with name '{file_name}':"]
+        for f in files:
+            output_parts.append(f"  - {f['name']} (ID: {f['id']})")
+        output_parts.append("\nChecking the first file...")
+        output_parts.append("")
+    else:
+        output_parts = []
+    
+    # Check permissions for the first file
+    file_id = files[0]['id']
+    
+    # Get detailed permissions
+    file_metadata = await asyncio.to_thread(
+        service.files().get(
+            fileId=file_id,
+            fields="id, name, mimeType, permissions, webViewLink, webContentLink, shared",
+            supportsAllDrives=True
+        ).execute
+    )
+    
+    permissions = file_metadata.get('permissions', [])
+    from gdrive.drive_helpers import check_public_link_permission, get_drive_image_url
+    has_public_link = check_public_link_permission(permissions)
+    
+    output_parts.extend([
+        f"File: {file_metadata['name']}",
+        f"ID: {file_id}",
+        f"Type: {file_metadata['mimeType']}",
+        f"Shared: {file_metadata.get('shared', False)}",
+        ""
+    ])
+    
+    if has_public_link:
+        output_parts.extend([
+            "✅ PUBLIC ACCESS ENABLED - This file can be inserted into Google Docs",
+            f"Use with insert_doc_image_url: {get_drive_image_url(file_id)}"
+        ])
+    else:
+        output_parts.extend([
+            "❌ NO PUBLIC ACCESS - Cannot insert into Google Docs",
+            "Fix: Drive → Share → 'Anyone with the link' → 'Viewer'"
+        ])
+    
+    return "\n".join(output_parts)
\ No newline at end of file
diff --git a/uv.lock b/uv.lock
index 89c6036..355ba62 100644
--- a/uv.lock
+++ b/uv.lock
@@ -2060,7 +2060,7 @@ wheels = [
 
 [[package]]
 name = "workspace-mcp"
-version = "1.3.4"
+version = "1.4.0"
 source = { editable = "." }
 dependencies = [
     { name = "aiohttp" },
